delegateを学ぼう
using System; namespace DelegateL2 { //delegate を定義 引数string 戻り値void delegate void Decorate(string s); class Program { static void Main(string[] args) { string str = "Hello"; //デリゲートにメソッド登録 Decorate dec = Star; //実行 dec(str); //デリゲートのメソッド付け替え dec = Atsign; dec(str); //追加登録 dec += Star; dec(str); //解除 dec -= Atsign; dec(str); //引数がstring一つ、戻り値がvoidのメソッドなら登録できる。 dec = Console.WriteLine; dec(str); } //引数がstring一つ戻り値がvoidのメソッド定義 static void Star(string s){ Console.WriteLine($"*{s}*"); } static void Atsign(string s){ Console.WriteLine($"@{s}@"); } } }
デリゲートはメソッドの引数に指定できる。
using System; namespace DelegateL2 { //delegate を定義 引数string 戻り値void delegate void Decorate(string s); class Program { static void Main(string[] args) { string str = "Hello"; //デリゲートを登録 StrDecorate(str, Star); //匿名型で登録 StrDecorate(str, delegate (string s) { Console.WriteLine($"@{s}@"); }); //ラムダ式 StrDecorate(str, (string s) => { Console.WriteLine($"@{s}@"); }); //引数の型は暗黙推論されるので省略可能、引数が一つの場合()も省略可能、文が一つの場合{}は省略可能、 StrDecorate(str, s => Console.WriteLine($"@{s}@")); string result=StrDecorate2(str, s => $"@{s}@"); Console.WriteLine(result); } static void StrDecorate(string str,Decorate dec){ dec(str); } static void Star(string s){ Console.WriteLine($"*{s}*"); } //自作のdelegateを作らなくても標準ライブラリでよく使うデリゲートは用意されている。 //以下はstringを引数で受け取ってstringを返すdelegate static string StrDecorate2(string str,Func<string,string> func){ return func(str); } } }
Q
以下の処理を順番に実現しよう。
- intの引数を2個戻り値がintのdelegate MathFuncを作成せよ
- MathFuncの仕様を満たすメソッドで二つの整数の和を返却するメソッドPlusを作成せよ。
- メインメソッドでMathFunc型の変数mfを用意しそこにPlusメソッドを登録せよ。
- 上記を利用して5と2の和を出力せよ。
- int型の引数2個とMathFunc型の引数1個戻り値intのメソッドCalcを作成せよ。メソッドの内容は二つのintの値をMathFuncで処理した値を返すメソッドすること。
- Calcに10と2とPlusを渡して結果を出力せよ。
- Calcの第三引数に匿名メソッドを用い、10と2の積を計算し出力せよ。
- Calcの第三引数にラムダ式を用いて10と2の商を求め出力せよ。
- Calcを用い二つの整数(10と2)の大きい方を表示せよ。
[実行例]
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DelegateSample { delegate int MathFunc(int x, int y); class Program { static void Main(string[] args) { MathFunc mf = Plus; Console.WriteLine(mf(5, 2)); Console.WriteLine(Calc(10, 2, Plus)); Console.WriteLine(Calc(10, 2, delegate (int x, int y) { return x * y; })); Console.WriteLine(Calc(10, 2, (x, y) => x / y)); Console.WriteLine(Calc(10, 2, (x, y) => x > y ? x:y)); //Console.WriteLine(Calc(10, 2, Math.Max)); } static int Plus(int x,int y) { return x + y; } static int Minus(int x,int y) { return x - y; } static int Calc(int x,int y,MathFunc mf) { return mf(x, y); } } }
今回は自分でデリゲートを用意したがライブラリにすでにあるデリゲートを利用すると上記Calcは以下のようにかける
static int Calc(int x,int y,Func<int,int,int> mf){}
ライブラリが用意しているよく使われるdelegate
Func<int> //引数なし、戻り値int Func<string,string> //引数string 1 戻り値string Func<int ,string,string> //引数がint,string 戻り値がstring Action //引数も戻り値もなし Action<string> void 引数1個 Action<int,int> void 引数2個
コメント