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++プログラマの方々には、声を大にしていいたい。関数ポインタは関数を特定する機能しか持たず、インスタンスを特定する情報は持たないのである。
Insider.NET 記事ランキング
本日
月間