連載

C#入門

第17回 処理を委譲するdelegate

(株)ピーデー
川俣 晶
2001/12/07


staticなメソッドへの委譲

 サンプル・プログラム2の例を見て、掛け算も足し算も完全に独立した処理であり、staticなメソッドにしても何ら問題ないことに気付いた人もいるだろう。では、staticなメソッドへの委譲は記述できるのだろうか? 以下はそのように修正してみたものである。

 1: using System;
 2:
 3: namespace ConsoleApplication22
 4: {
 5:   delegate int Sample( int x, int y );
 6:   class Class2
 7:   {
 8:     public static int methodMult( int x, int y )
 9:     {
10:       return x*y;
11:     }
12:     public static int methodPlus( int x, int y )
13:     {
14:       return x+y;
15:     }
16:   }
17:   class Class1
18:   {
19:     public static void calc( int x, int y, Sample calcMethod )
20:     {
21:       int result = calcMethod( x, y );
22:       Console.WriteLine( result );
23:     }
24:     static void Main(string[] args)
25:     {
26:       calc( 2, 3, new Sample( Class2.methodMult ) );
27:       calc( 2, 3, new Sample( Class2.methodPlus ) );
28:     }
29:   }
30: }
移譲先のメソッドをstaticにしたサンプル・プログラム3
methodMultメソッドとmethodPlusメソッドをstaticに変更している。

 これを実行すると以下のようになる。

サンプル・プログラム3の実行結果
実行結果はサンプル・プログラム2とまったく同じである。

 他の多くの場合と同じように、staticなメソッドを指定するために、インスタンス名の代わりにクラス名を使用することができる。26行目のようにClass2.methodMultのようにメソッド名を記述すれば、そのままstaticなメソッドを利用可能である。それ以外には特別な記述はなく、delegateの宣言や呼び出し時に特別な配慮は必要ないことが分かると思う。

delegateはインスタンスを選ぶ

 これは非常に重要なことなので、よく頭に刻み込んでほしいところなのだが、staticなメソッドを使う場合を除き、delegateはインスタンスとメソッドの情報を扱う。つまり、delegateが委譲する先は、ただ単に指定されたメソッドが呼ばれるだけでなく、呼び出し時にインスタンスも明示される。以下は、複数インスタンスのメソッドを委譲先として使用したサンプル・ソースである。

 1: using System;
 2:
 3: namespace ConsoleApplication23
 4: {
 5:   delegate void Sample( int x, int y );
 6:   class Class2
 7:   {
 8:     public int result;
 9:     public void method( int x, int y )
10:     {
11:       result = x * y;
12:     }
13:   }
14:   class Class1
15:   {
16:     static void Main(string[] args)
17:     {
18:       Class2 instance1 = new Class2();
19:       Class2 instance2 = new Class2();
20:       Sample d1 = new Sample( instance1.method );
21:       Sample d2 = new Sample( instance2.method );
22:       d1(2,3);
23:       d2(4,5);
24:       Console.WriteLine( instance1.result );
25:       Console.WriteLine( instance2.result );
26:     }
27:   }
28: }
複数インスタンスに対するdelegateを使用したサンプル・プログラム4
2つのインスタンスとそのdelegateを生成し、それぞれ異なる値で計算を行う。

 これを実行すると以下のようになる。

サンプル・プログラム4の実行結果
それぞれのインスタンスの持つ計算結果が表示されている。

 ここでは、同じClass2クラスのインスタンスを2つ作成している(18〜19行目)。この2つのインスタンスに対して別々にdelegateインスタンスを作成している(20〜21行目)。さてここからが、このサンプル・ソース最大の注目点なのだが、22〜23行目のメソッド呼び出しには、どのClass2インスタンスを対象にするか、明示的には表現されていない。しかし、delegateインスタンスは、どのClass2インスタンスを対象とするかを覚えているので、間違いなく20〜21行目で指定されたClass2インスタンスのメソッドを呼び出す。

 このように、delegateはメソッドだけでなくインスタンスも識別することをよく覚えておいていただきたい。特にC/C++プログラマの方々には、声を大にしていいたい。関数ポインタは関数を特定する機能しか持たず、インスタンスを特定する情報は持たないのである。


 INDEX
  第17回 処理を委譲するdelegate
    1.delegateとは何か
  2.staticなメソッドへの委譲
    3.戻り値と引数が合えば委譲できる
    4.delegateをオブジェクトとして使う
    5.移譲先リストの変更

「C#入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間