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個

コメント