スポンサーリンク
※サイト運営にサーバーは必須です※
~このサイトもエックスサーバーを使用しています~
マルチキャストデリゲートとは?
デリゲートは、複数のメソッドの参照情報を格納できます。
マルチキャストデリゲートを使用することで、デリゲートを介して、複数のメソッドをまとめて実行できます。
マルチキャストデリゲートに、デリゲートインスタンスを追加する場合は「+」演算子を使用します。
逆に、登録したデリゲートインスタンスを1つ削除する場合は、「-」演算子を使用します。
削除したいデリゲートインスタンスが、同一名称かつ複数ある場合は、その数だけ「-」演算子が必要になります。
削除する時は、新しく追加されたデリゲートインスタンスから順番に削除されていきます。
万が一、あるデリゲートインスタンスに対して、過剰に削除してもエラーにはなりません。
ただし、全てのデリゲートインスタンスを削除した状況で、登録したメソッドを呼び出そうとすると、以下のようなエラーが起きます。
ハンドルされていない例外: System.NullReferenceException: オブジェクト参照がオブジェクト インスタンスに設定されていません。
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Multicast02 { class Program { delegate void Del(); static void Hello() { Console.WriteLine("こんにちは"); } static void Morning() { Console.WriteLine("おはようございます"); } static void Main(string[] args) { Del message; //1回目 message = Hello; message += Hello; message += Morning; message += Hello; message += new Del(Hello); Console.WriteLine("1回目"); message(); //2回目(Morningの後に追加されたHelloに対応するデリゲートインスタンスが削除されることを確認) message -= Hello; Console.WriteLine("2回目"); message(); //3回目(Morningに対応するデリゲートインスタンスを過剰に削除) message -= Morning; message -= Morning; Console.WriteLine("3回目"); message(); //4回目(全てのデリゲートインスタンスを削除) //エラーになるためコメントアウト //message -= Hello; //message -= Hello; //Console.WriteLine("4回目"); //message(); } } } |
実行結果
1回目
こんにちは
こんにちは
おはようございます
こんにちは
こんにちは
2回目
こんにちは
こんにちは
おはようございます
こんにちは
3回目
こんにちは
こんにちは
こんにちは
message += Hello;
このような書き方だと、メソッドを追加しているように見えますが、正確に言えば、メソッドを参照しているデリゲートインスタンスを追加しています。
そのため、上のコードは以下のようなコードの簡易表現したコードになります。
message += new Del(Hello);
同じデリゲート型の演算
同じデリゲート型同士で「+」「-」演算子の使用は可能です。
ただし、戻り値と引数が同じもデリゲート名が異なれば、異なる型だと認識され、「+」「-」演算子は使用できません。
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Multicast03 { class Program { delegate void Del(); delegate void Del1(); delegate void Del2(); static void Hello() { Console.WriteLine("こんにちは"); } static void Morning() { Console.WriteLine("おはようございます"); } static void Main(string[] args) { Del message1 = Hello; Del message2 = Morning; Del multi = message1 + message2; multi(); //下のような書き方はできない //Del1 message1= Hello; //Del2 message2 = Morning; //Del multi = message1+ message2; //戻り値と引数が同じデリゲート型でも名前が異なれば、異なる型だと認識されます } } } |
実行結果
こんにちは
おはようございます
戻り値のあるメソッドに対して、マルチキャストを使用する場合
戻り値のあるメソッドに対して、「+」演算子を使って、複数のメソッドを束ねたとします。
この戻り値のある複数のメソッドを呼び出し場合、最後のメソッドの戻り値が最終的な結果となります。
ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Multicast04 { class Program { delegate string Del(); static string Hello() { return "こんにちは"; } static string Morning() { return "おはようございます"; } static void Main(string[] args) { Del message = Hello; message += Morning; string str = message(); Console.WriteLine(str); } } } |
実行結果
おはようございます
Morningメソッドのみ最終的な結果に反映されています。Helloメソッドの結果は表には現れません。
このように戻り値のある場合に、マルチキャストデリゲートを使用しても、あまりメリットがありません。
そのため、マルチキャストデリゲートを使用する場合は、戻り値がvoid型であることが多いです。
~プログラミングを勉強してみませんか?~
TechAcademy [テックアカデミー] は無料の体験講座が用意されているので、気軽に体験できます。
※私(サイト主)も無料体験講座を実際に受けてみました(→感想)