C#(delegate)

C#

delegateを学ぼう

01using System;
02 
03namespace DelegateL2
04{
05    //delegate を定義 引数string 戻り値void
06    delegate void Decorate(string s);
07    class Program
08    {
09         
10        static void Main(string[] args)
11        {
12            string str = "Hello";
13            //デリゲートにメソッド登録
14            Decorate dec = Star;
15            //実行
16            dec(str);
17            //デリゲートのメソッド付け替え
18            dec = Atsign;
19            dec(str);
20            //追加登録
21            dec += Star;
22            dec(str);
23            //解除
24            dec -= Atsign;
25            dec(str);
26            //引数がstring一つ、戻り値がvoidのメソッドなら登録できる。
27            dec = Console.WriteLine;
28            dec(str);
29        }
30        //引数がstring一つ戻り値がvoidのメソッド定義
31        static void Star(string s){
32            Console.WriteLine($"*{s}*");
33        }
34        static void Atsign(string s){
35            Console.WriteLine($"@{s}@");
36        }
37    }
38}

デリゲートはメソッドの引数に指定できる。

01using System;
02 
03namespace DelegateL2
04{
05    //delegate を定義 引数string 戻り値void
06    delegate void Decorate(string s);
07    class Program
08    {
09         
10        static void Main(string[] args)
11        {
12            string str = "Hello";
13            //デリゲートを登録
14            StrDecorate(str, Star);
15            //匿名型で登録
16            StrDecorate(str, delegate (string s) {
17                Console.WriteLine($"@{s}@");
18            });
19            //ラムダ式
20            StrDecorate(str, (string s) => { Console.WriteLine($"@{s}@"); });
21            //引数の型は暗黙推論されるので省略可能、引数が一つの場合()も省略可能、文が一つの場合{}は省略可能、
22            StrDecorate(str, s => Console.WriteLine($"@{s}@"));
23 
24            string result=StrDecorate2(str, s => $"@{s}@");
25            Console.WriteLine(result);
26 
27            
28        }
29        static void StrDecorate(string str,Decorate dec){
30            dec(str);
31        }
32        static void Star(string s){
33            Console.WriteLine($"*{s}*");
34        }
35        //自作のdelegateを作らなくても標準ライブラリでよく使うデリゲートは用意されている。
36        //以下はstringを引数で受け取ってstringを返すdelegate
37        static string StrDecorate2(string str,Func<string,string> func){
38            return func(str);
39        }
40 
41    }
42}

Q
以下の処理を順番に実現しよう。

  1. intの引数を2個戻り値がintのdelegate MathFuncを作成せよ
  2. MathFuncの仕様を満たすメソッドで二つの整数の和を返却するメソッドPlusを作成せよ。
  3. メインメソッドでMathFunc型の変数mfを用意しそこにPlusメソッドを登録せよ。
  4. 上記を利用して5と2の和を出力せよ。
  5. int型の引数2個とMathFunc型の引数1個戻り値intのメソッドCalcを作成せよ。メソッドの内容は二つのintの値をMathFuncで処理した値を返すメソッドすること。
  6. Calcに10と2とPlusを渡して結果を出力せよ。
  7. Calcの第三引数に匿名メソッドを用い、10と2の積を計算し出力せよ。
  8. Calcの第三引数にラムダ式を用いて10と2の商を求め出力せよ。
  9. Calcを用い二つの整数(10と2)の大きい方を表示せよ。

[実行例]

01using System;
02using System.Collections.Generic;
03using System.Linq;
04using System.Text;
05using System.Threading.Tasks;
06 
07namespace DelegateSample
08{
09    delegate int MathFunc(int x, int y);
10    class Program
11    {
12        static void Main(string[] args)
13        {
14            MathFunc mf = Plus;
15            Console.WriteLine(mf(5, 2));
16            Console.WriteLine(Calc(10, 2, Plus));
17            Console.WriteLine(Calc(10, 2, delegate (int x, int y) { return x * y; }));
18            Console.WriteLine(Calc(10, 2, (x, y) => x / y));
19            Console.WriteLine(Calc(10, 2, (x, y) => x > y ? x:y));
20            //Console.WriteLine(Calc(10, 2, Math.Max));
21        }
22        static int Plus(int x,int y)
23        {
24            return x + y;
25        }
26        static int Minus(int x,int y)
27        {
28            return x - y;
29        }
30        static int Calc(int x,int y,MathFunc mf)
31        {
32            return mf(x, y);
33        }
34         
35    }
36}

今回は自分でデリゲートを用意したがライブラリにすでにあるデリゲートを利用すると上記Calcは以下のようにかける

1static int Calc(int x,int y,Func<int,int,int> mf){}

ライブラリが用意しているよく使われるdelegate

1Func<int> //引数なし、戻り値int
2Func<string,string> //引数string 1 戻り値string
3Func<int ,string,string> //引数がint,string 戻り値がstring
4Action //引数も戻り値もなし
5Action<string> void 引数1個
6Action<int,int> void 引数2個

コメント

タイトルとURLをコピーしました