C# 入門 & 実践 / C sharp

4-26. デリゲート - 2 - static デリゲート / マルチキャストデリゲート


まずstaticデリゲートです。
先ほどの例で掛け算固定で使う場合は、staticデリゲートとして宣言してしまえば
いちいち利用ごとに宣言しなくて済みます。

    class MyTester
    {
        // delegate 用 メソッド 1
        public static int Kakezan(int i, int cnt)
        {
            return i * cnt;
        }
        // ここで宣言してしまう!
        public static readonly BbDelegate.SetCnt kake = new BbDelegate.SetCnt(Kakezan);


        static void Main()
        {
            BbDelegate b1 = new BbDelegate(10);

            MyTester mt = new MyTester();
            
            // デリゲートを作成!
            // 掛け算バージョン
            // 既に出来ています!BbDelegate.SetCnt kake = new BbDelegate.SetCnt( Kakezan );

            // 掛け算を使ってみる。
            b1.UseFunc(kake);
            
            // readonly なのでコンパイルできません!
            // kake = new BbDelegate.SetCnt( Tashizan );

        }
    }

このクラスではこのメソッドをデリゲートして使用すると決まっている場合は
最初に static readonly として宣言しておいたほうがいいでしょう。

2. マルチキャスト

1つのデリゲートを通じて2つ以上のメソッドを呼び出すことが出来ます。
イベントで重要になるらしいです。
この例では、cnt を参照渡しにして、データを保持したままメソッドを続けます。

    class BbDelegate
    {
        private int cnt = 0;

        public BbDelegate(int i)
        {
            cnt = i;
        }

        // delegate メソッド宣言
        public delegate int SetCnt(int i,ref int cnt);

        // SetCont を使用するメソッド
        public void UseFunc(SetCnt func)
        {
            func( 5, ref cnt );
            Console.WriteLine("cnt : {0}", cnt);
        }
    }

    class MyTester
    {
        // delegate 用 メソッド 1
        public static int Kakezan(int i, ref int cnt)
        {
            cnt = i * cnt;
            Console.WriteLine("掛け算が呼ばれたよ cnt = {0}", cnt);
            return cnt;
        }
        // delegate 用 メソッド 2
        public static int Tashizan(int i, ref int cnt)
        {
            cnt = i + cnt;
            Console.WriteLine("足し算が呼ばれたよ cnt = {0}", cnt);
            return cnt;
        }
        // delegate 用 メソッド 3
        public static int Hikizan(int i, ref int cnt)
        {
            cnt = i - cnt;
            Console.WriteLine("引き算が呼ばれたよ cnt = {0}", cnt);
            return cnt;
        }

        static void Main()
        {
            BbDelegate b1 = new BbDelegate(10);

            // デリゲートを作成!
            // 掛け算バージョン
            BbDelegate.SetCnt kake = new BbDelegate.SetCnt( Kakezan );
            // 足し算バーション
            BbDelegate.SetCnt tashi = new BbDelegate.SetCnt(Tashizan);
            // 引き算バーション
            BbDelegate.SetCnt hiki = new BbDelegate.SetCnt(Hikizan);

            BbDelegate.SetCnt multi;

            multi = kake + tashi;

            // 掛け算と足し算を行う。
            b1.UseFunc(multi);

            multi += hiki;
            // 掛け算と足し算と引き算を行う。
            b1.UseFunc(multi);

            multi -= kake;
            // 足し算と引き算を行う。
            b1.UseFunc(multi);
        }
    }

掛け算が呼ばれたよ cnt = 50
足し算が呼ばれたよ cnt = 55
cnt : 55
掛け算が呼ばれたよ cnt = 275
足し算が呼ばれたよ cnt = 280
引き算が呼ばれたよ cnt = -275
cnt : -275
足し算が呼ばれたよ cnt = -270
引き算が呼ばれたよ cnt = 275
cnt : 275

このように連続で、cntを四則演算します^-^。


参照渡しにしないでreturnで返していくと

    class BbDelegate
    {
        private int cnt = 0;

        public BbDelegate(int i)
        {
            cnt = i;
        }

        // delegate メソッド宣言
        public delegate int SetCnt(int i, int cnt);

        // SetCont を使用するメソッド
        public void UseFunc(SetCnt func)
        {
            cnt = func( 5, cnt );
            Console.WriteLine("cnt : {0}", cnt);
        }
    }

    class MyTester
    {
        // delegate 用 メソッド 1
        public static int Kakezan(int i, int cnt)
        {
            cnt = i * cnt;
            Console.WriteLine("掛け算が呼ばれたよ cnt = {0}", cnt);
            return cnt;
        }
        // delegate 用 メソッド 2
        public static int Tashizan(int i, int cnt)
        {
            cnt = i + cnt;
            Console.WriteLine("足し算が呼ばれたよ cnt = {0}", cnt);
            return cnt;
        }
        // delegate 用 メソッド 3
        public static int Hikizan(int i, int cnt)
        {
            cnt = i - cnt;
            Console.WriteLine("引き算が呼ばれたよ cnt = {0}", cnt);
            return cnt;
        }

        static void Main()
        {
            BbDelegate b1 = new BbDelegate(10);

            // デリゲートを作成!
            // 掛け算バージョン
            BbDelegate.SetCnt kake = new BbDelegate.SetCnt( Kakezan );
            // 足し算バーション
            BbDelegate.SetCnt tashi = new BbDelegate.SetCnt(Tashizan);
            // 引き算バーション
            BbDelegate.SetCnt hiki = new BbDelegate.SetCnt(Hikizan);

            BbDelegate.SetCnt multi;

            multi = kake + tashi;

            // 掛け算と足し算を行う。
            b1.UseFunc(multi);

            multi += hiki;
            // 掛け算と足し算と引き算を行う。
            b1.UseFunc(multi);

            multi -= kake;
            // 足し算と引き算を行う。
            b1.UseFunc(multi);
        }
    }


掛け算が呼ばれたよ cnt = 50
足し算が呼ばれたよ cnt = 15
cnt : 15
掛け算が呼ばれたよ cnt = 75
足し算が呼ばれたよ cnt = 20
引き算が呼ばれたよ cnt = -10
cnt : -10
足し算が呼ばれたよ cnt = -5
引き算が呼ばれたよ cnt = 15
cnt : 15

このように、 cnt = の部分は実行されずに次へ進むのでcntは一番最後に呼ばれたメソッドの返り値になります!




4-25. デリゲート と イベント - 1 - デリゲートって何ですか? « 4. C# 入門 Level 2


C# 入門 & 実践 / C sharp