ホームに戻る
著作権・免責 事項

C#を使ってみる

ここではC#を実際に使ってみてJavaには無い機能をいくつか紹介します。
決して入門ではないので注意してください。
ここのプログラムはMicrosoft.NET Framework SDK Beta1 英語ベータ版で動作確認しています。
インデントに全角スペースを使ってますので注意してください。

コンパイルオプション
ハローワールド
ボクシング
可変引数
ref/outパラメータ
演算子オーバーロード
インデクサ
デリゲート
ポインタ

・コンパイルオプション


/target:library dllを作成する
/out:file-name 指定したファイルでマネッジドコード作成
/define:DEBUG デバッグオプションでマネッジドコード作成
/nooutput シンタックスチェックのみ
/unsafe unsafe文を許可
/r:dll-file dllを結合
※オプションは他にもあります

・ハローワールド

お約束のプログラムです。
C#の場合、メインの戻り値はvoidかintが指定できる。
引数は、stringの配列かvoidが指定できる。
using System;

public class Hello
{
   public static void Main( string[] args ){
      Console.WriteLine( "Hello World" );
   }
}

実行結果
C:\My Documents\C#\Hello world>hello
Hello World

・ボクシング(boxing)

ボクシングとは必要に応じて値型(int,char etc)を参照型(class)に変換する機能のことです。
逆をアンボクシング(unboxing)と呼びます。
using System;

class Boxing
{
public static void Main(){
      int i = 10;
      object o = i;
      Console.WriteLine( o );

      int j = (int)o;
      Console.WriteLine( j );
   }
}

実行結果
C:\My Documents\C#\boxing>boxing
10
10

・可変引数

可変引数でメソッドを呼び出します。
C言語のような面倒な処理は必要ありません。
using System;

class Params
{
   public static void print( char c, params object[] o ){
      Console.Write( "{0} ", c );
      for( int i = 0; i < o.Length; i++ )
         Console.Write( "{0} ", o[i] );
      Console.Write( '\n' );
   }

   public static void Main(){
      string[] s = { "abc", "def" , "ghi" };
      print( 'A', s );
      print( 'A', 10, 12.34, 'B', "abc" );
   }
}

実行結果
C:\My Documents\C#\params>params
A abc def ghi
A 10 12.34 B abc

・ref/outパラメータ

引数にref/outパラメータを付けます。
VBでおなじみなので説明は省きます。
using System;

public class ref_out
{
   public static void swap( ref int p1, ref int p2 ){
      int temp = p1;
      p1 = p2;
      p2 = temp;
   }

   public static void sum( int p1, int p2, out int p3 ){
      p3 = p1 + p2;
   }

   public static void Main(){
      int x = 10, y = 20, z = 0;

      Console.Write( "x = {0}, y = {1}\n", x, y );
      swap( ref x, ref y );
      Console.Write( "x = {0}, y = {1}\n", x, y );

      sum( x, y, out z );
      Console.Write( "{0} + {1} = {2}\n", x, y, z );
   }
}

実行結果
C:\My Documents\C#\ref_out>ref_out
x = 10, y = 20
x = 20, y = 10
20 + 10 = 30

・演算子オーバーロード

C#では演算子をオーバーロードできます。
ここでは*を例にします。
using System;

class MyString
{
   private string str;

   public MyString(string s){ str = s; }
   public MyString(){ str = ""; }

   public static MyString operator*( MyString s, int n ){
      MyString ret = new MyString();
      for( int i = 0; i < n; i++ ){
         ret.str += s.str;
      }
      return ret;
   }

   public override string ToString(){
      return str;
   }

class run
{
   public static void Main(){
      MyString m = new MyString("abc ");
      Console.Write( m * 5 );
   }
}

実行結果
C:\My Documents\C#\operator>operator
abc abc abc abc abc

・インデクサ(indexer)

インデクサを使うと配列でない要素に添字を使用できます。
ここでは簡単なリストを作成し、添字を用いてアクセスします。
using System;

public class list
{
   private static int item = 1;
   private object value;
   private list next;

   public list( object o ){
      value = o;
      next = null;
   }

   public object get( int index ){
      if( index > item - 1 )
         return "index error";

      list l = this;
      while( index != 0 ){
         l = l.next;
         index--;
      }
      return l.value;
   }

   public void set( int index, object value ){
      if( index > item - 1 ){
         Console.Write( "index error" );
         return;
      }

      list l = this;
      while( index != 0 ){
         l = l.next;
         index--;
      }
      l.value = value;
   }

   public object this[int index]{
      get{ return this.get(index); }
      set{ this.set( index, value ); }
   }

   public void add( object o ){
      list l = this;
      while( l.next != null )
         l = l.next;
      l.next = new list( o );
      item++;
   }

   public void show(){
      list l = this;
      Console.WriteLine( "item : {0}", item );
      do{
         Console.WriteLine( l.value );
         l = l.next;
      }while( l != null );
      Console.Write( '\n' );
   }
}

public class run
{
   public static void Main(){
      list l = new list( "item1" );
      l.add( "item2" );
      l.add( 300 );
      l.show();

      object o = l[0];
      l[0] = l[1];
      l[1] = o;
      l.show();

      Console.WriteLine( l[2] );
      Console.WriteLine( l[3] );
   }
}

実行結果
C:\My Documents\C#\indexer>indexer
item : 3
item1
item2
300

item : 3
item2
item1
300

300
index error

・デリゲート(delegate)

デリゲートとは関数ポインタのようなものです。
シグネチャさえ同じであればstaticでもdynamicでも呼び出せます。
using System;

class A
{
   private string[] jp, us;

   public A(){
      jp = new string[]{ "零", "壱", "弐", "参" };
      us = new string[]{ "zero", "one", "two", "three" };
   }

   public string getJP( int i ){
      return jp[i];
   }

   public string getUS( int i ){
      return us[i];
   }
}

delegate string MyDelegate( int i );

class run
{
   public static void Main(){
      A a = new A();
      MyDelegate[] del = { new MyDelegate( a.getJP ), new MyDelegate( a.getUS ) };
      for( int i = 0; i < 4; i++ )
         Console.WriteLine( "{0},{1}", del[0](i), del[1](i) );
   }
}

実行結果
C:\My Documents\C#\delegate>delegate
零,zero
壱,one
弐,two
参,three

・ポインタ

C#では一応ポインタも扱えます。
ポインタにインクリメント、デクリメントを使用するとエラーが出ます。
.NETプラットフォームはコンポーネント指向なので、
マネッジドC++で作成したほうが良いような気もします。
using System;

class Pointer
{
   unsafe public static void add( int[] i ){
      fixed( int *pfix = i ){
         int *p = pfix;
         for( int j = 0; j < i.Length; j++ ){
            *p += 1;
            p += 1;
         }
      }
   }

   public static void Main(){
      int[] i = new int[10];
      for( int j = 0; j < i.Length; j++ )
         i[j] = j;
      foreach( int p in i )
         Console.Write( "{0} ", p );
      Console.Write( '\n' );
      add( i );
      foreach( int p in i )
         Console.Write( "{0} ", p );
      Console.Write( '\n' );
   }
}

実行結果
C:\My Documents\C#\pointer>pointer
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10


Copyright (C) 1999 System Infinity Corporation. All rights reserved.