コンピュータクワガタ

かっぱのかっぱによるコンピュータ関連のサイトです

C#の学習 No. 9 delegate

http://ufcpp.net/study/csharp/sp_delegate.html
を参考にdelegateの学習。
ラムダ式と絡んできて難しかった。
別に、ラムダ式を学習しないといけないな。

namespace Sample
{
    public delegate String DelegateMethod(int i);

    public class DelegateTest
    {
        public String Message(int i)
        {
            return "instance " + i;
        }

        public String Message2(int i)
        {
            System.Console.WriteLine("Message2!");
            return "instance2 " + i;
        }

        public String Message3(int i)
        {
            System.Console.WriteLine("Message3!");
            return "instance2 " + i;
        }

        // delegateを引数とする。
        public void ShowMessage(DelegateMethod d)
        {
            System.Console.WriteLine("ShowMessage(100): " + d(100));
        }

        public static String StaticMessage(int i)
        {
            return "static " + i;
        }

        public static void Main(string[] args)
        {
            DelegateTest delegateTest = new DelegateTest();
            DelegateMethod delegateMethod;
            
            //***** インスタンスのメソッドを渡す場合
            delegateMethod = new DelegateMethod(delegateTest.Message);
            System.Console.WriteLine("instance(1): " + delegateMethod(1));

            //***** インスタンスメソッドの別バージョン
            //      ver. 2.0から
            delegateMethod = delegateTest.Message;
            System.Console.WriteLine("instance(2): " + delegateMethod(2));

            //***** インスタンスメソッドの匿名版
            //      ver. 2.0から
            delegateMethod = delegate(int n) {
                return "インスタンス匿名 " + n;
            };
            System.Console.WriteLine("instance(3): " + delegateMethod(3));

            //***** インスタンスメソッドのラムダ式
            //      ver. 3.0から
            //      括弧がなくても動くけど、書かないとわけわからないな。
            delegateMethod = n => "インスタンスラムダ式 " + n;
            System.Console.WriteLine("instance(4): " + delegateMethod(4));

            //***** インスタンスメソッドの別バージョン
            //      足し算で複数、順番通りに動く!!
            delegateMethod = new DelegateMethod(delegateTest.Message2);
            delegateMethod += delegateTest.Message2;
            delegateMethod += new DelegateMethod(delegateTest.Message3);
            // 戻り値は最後のもののみ
            System.Console.WriteLine("instance(5): " + delegateMethod(5));

            //***** スタティックのメソッドを渡す場合
            delegateMethod = new DelegateMethod(StaticMessage);
            System.Console.WriteLine("static(1): " + delegateMethod(1));

            //***** スタティックのメソッドの別バージョン
            //      ver. 2.0から
            delegateMethod = StaticMessage;
            System.Console.WriteLine("static(2): " + delegateMethod(2));

            //***** 引数にdelegate
            delegateTest.ShowMessage(new DelegateMethod(delegateTest.Message));

            //***** 引数にdelegate 匿名版
            //      ver. 2.0から
            delegateTest.ShowMessage(delegate(int n) {
                return "匿名 " + n;
            });

            //***** 引数にdelegate 匿名版 ラムダ式
            //      ver. 3.0から
            delegateTest.ShowMessage(
                (int n) => { return "ラムダ " + n; }
            );

            //***** 引数にdelegate 匿名版 ラムダ式2
            //      ver. 3.0から
            delegateTest.ShowMessage(
                (n) => "ラムダ2 " + n
            );

            //***** 引数にdelegate 匿名版 ラムダ式3
            //      ver. 3.0から
            delegateTest.ShowMessage(
                n => "ラムダ3 " + n
            );
        }
    }
}