あんまり今まで縁がなかったdelegateを触ってみる。
参照 : http://ufcpp.net/study/csharp/sp_delegate.html
C#では、delegateはメソッドを代入するための変数の型、メソッドを参照するための型。
- サンプル(これはクラスメソッドの例)
using System; // int型の引数一つをとって何も値を返さないdelegate型 delegate void TestDelegateMethod(int a); class DelegateTest { static void Main() { TestDelegateMethod a = A; a(256); } static void A(int n) { Console.Write("A{0}がよばれました\n", n); } }
インスタンスメソッドでもクラスメソッドでも代入可能
using System; // 引数を取らず、何も返さない delegate void ShowMessage(); class Person { string name; public Person(string name) { this.name = name; } public void ShowName() { Console.Write("名前 {0}\n", this.name); } } class TestDelegate { static void Main() { Person p = new Person("テスト"); ShowMessage show = p.ShowName; show(); } }
複数メソッドを代入可能(マルチキャストデリゲート)
+= 演算子で複数のメソッドを代入可能です。
using System; delegate void ShowMessage(); class DelegateTest { static void Main() { ShowMessage a = A; a += B; a += C; a(); } static void A() { Console.Write("Aだよ\n"); } static void B() { Console.Write("Bだよ\n"); } static void C() { Console.Write("Cだよ\n"); } }
非同期呼び出し
デリゲート型を定義すると、BeginInvoke と EndInvoke というメソッドを生やす。
BeginInvokeは、System.AsyncCallback デリゲート型の引数および object 型の引数をとり、System.IAsyncResult インターフェース型の値を返す。 EndInvoke はデリゲート型の定義時に ref または out キーワードを付けた引数および System.IAsyncResult インターフェース型の引数を持ち、デリゲートの戻り値と同じ型の戻り値を返す。
using System; using System.Threading; namespace A { public delegate void ShowMessage(int n); public class DelegateTest { static void Main() { const int N = 6; ShowMessage asyncCall = AsyncMethod; // asysCall を非同期を呼び出し // BeginInvokeで IAsyncResult ar = asyncCall.BeginInvoke(N, null, null); for (int i=0; i<N; ++i) { Thread.Sleep(600); Console.Write("Main {0}\n", i); } // asyncCall の処理が終わるの待つ asyncCall.EndInvoke(ar); Console.Write("処理完了"); } static void AsyncMethod(int n) { for(int i=0; i<n; ++i) { Thread.Sleep(1000); Console.Write("AsyncMethod {0}\n", i); } } } }