かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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を配列でゲットして自分でループで回して戻り値を集めてまわったり、例外が出たときにも継続して続きの処理を呼び出したり出来るってことが出来るようになるのです。

知らなかった。