佐々木屋

技術的なことから趣味まで色々書きます

デリゲートの使いどころ ③(マルチキャストデリゲート)

一つのデリゲートで複数のメソッドを連続で実行することをマルチキャストデリゲートと呼びます。これによってメソッドを任意のタイミングで追加して最後に実行するような処理も簡潔に書くことができます。

例えば以下のようなメソッドをデリゲートで呼ぶとします。

private delegate void TestDlgt();
private void Method1() {
    Console.WriteLine("hoge");
}
private void Method2() {
    Console.WriteLine("piyo");
}
private void Method3() {
    Console.WriteLine("fuga");
}
Private Delegate Sub TestDlgt()
Private Sub Method1()
    Console.WriteLine("hoge")
End Sub
Private Sub Method2()
    Console.WriteLine("piyo")
End Sub
Private Sub Method3()
    Console.WriteLine("fuga")
End Sub


メソッドの追加

C#は+演算子でメソッドを追加していきます。

TestDlgt dgt = new TestDlgt(Method1);
dgt += Method2;
dgt += Method3;
dgt();

VB.NETは少し面倒くさいです。System.DelegateクラスのCombineメソッドに連結するメソッドを渡して追加します。Combineメソッドの戻り値はSystem.Delegate型なので、DirectCastかCTypeで型変換が必要です。

Dim dgt1 As TestDlgt = New TestDlgt(AddressOf Method1)
dgt1 = DirectCast([Delegate].Combine(dgt1, New TestDlgt(AddressOf Method2)), TestDlgt)
dgt1 = DirectCast([Delegate].Combine(dgt1, New TestDlgt(AddressOf Method3)), TestDlgt)
dgt1()
hoge
piyo
fuga



C#でもCombineメソッドで追加できますが、面倒なのであまり利用されません。

TestDlgt dgt = new TestDlgt(Method1);
dgt = (TestDlgt)Delegate.Combine(dgt, new TestDlgt(Method2));
dgt = (TestDlgt)Delegate.Combine(dgt, new TestDlgt(Method3));
dgt();


削除

C#は-演算子で削除します。

dgt -= Method2;
dgt();

VB.NETはSystem.DelegateクラスのRemoveメソッドに削除するメソッドを渡します。

dgt1 = DirectCast([Delegate].Remove(dgt1, New TestDlgt(AddressOf Method2)), TestDlgt)
dgt1()
hoge
fuga

C#でもRemoveメソッドは利用可能です。

dgt = (TestDlgt)Delegate.Remove(dgt, new TestDlgt(Method2));
dgt();



削除は追加した数だけ必要ですが、過剰に削除しても特にエラーになるようなことはありません。