かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Delegateの復習をした

最近プログラミング.NET Frameworkを読んでるのですが、目から鱗がポロポロ落ちたり、忘れてた基本的なこととかを思い出させてくれたりとても勉強になってます。

そんな中慣れ親しんでたはずのDelegateの動作確認のためのプログラムを書いたのでメモメモ

namespace DelegateBasic
{
    using System;

    /// <summary>
    /// Delegateの復習
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            Action a1 = () => Console.WriteLine("Action1");
            Action a2 = () => Console.WriteLine("Action2");
            Action a3 = () => Console.WriteLine("Action3");

            // DelegateのCombineメソッド忘れてた
            {
                // 結合!!
                var a = Delegate.Combine(a1, a2, a3) as Action;
                Console.WriteLine("Delegate.Combine(a1, a2, a3)");
                a();
            }

            // +=と同じ意味なんだね
            {
                var a = new Action(a1);
                a += a2;
                a += a3;
                Console.WriteLine("+= operator");
                a();
            }

            // 結合したDelegateの中身が取れる
            {
                var a = Delegate.Combine(a1, a2, a3) as Action;

                Console.WriteLine("GetInvocationList()");
                // 内部のDelegateの配列をゲット
                Delegate[] actions = a.GetInvocationList();
                // 順番に呼び出す
                foreach (Action action in actions)
                {
                    action();
                }
            }
        }
    }
}

最後の、通常のDelegateの呼び出しは最後に実行されたDelegateの結果しか返さないのと、途中で例外が出たらそこで動きが止まってしまうという挙動がデフォルトです。その挙動で満足できないときはGetInvocationListで内部のDelegateを配列でゲットして自分でループで回して戻り値を集めてまわったり、例外が出たときにも継続して続きの処理を呼び出したり出来るってことが出来るようになるのです。

知らなかった。