C#-デリゲート
委任とは何ですか
デリゲート函数指针
はい升级版
。C# ではデリゲートを使用して、C/C++ 言語の関数ポインター関数を完了します。関数ポインターと比較して、デリゲートはより多くの関数を完了できます。
Java に精通している場合は、Java にはデリゲートも関数ポインターもないことがわかるでしょう。Java では、Java はインターフェースを使用してこの操作を完了します。特に Java 8 以降では函数式接口
、その意図がより明白です。
メソッドはデリゲートを使用して間接的に呼び出すことができます。
委托滥用会造成灾难
したがって、C# では、Java インターフェイスを使用していくつかの委任された関数を実行する方法を学ぶことができます。
システムの事前定義されたデリゲートを使用する
アクション
Action は、戻り値がなく空のパラメーター リストを持つメソッドへのデリゲートです。
class Pragram
{
static void Main(string[] args)
{
Calc calc = new Calc();
Action action = new Action(calc.PrintInfo);
// 委托调用
action.Invoke();
action(); // 简洁写法
}
}
class Calc
{
public void PrintInfo()
{
Console.WriteLine("class Calc.");
}
}
ファンク
Func には 17 のジェネリック型があり、異なる数のパラメーター リストを持つメソッドに対応するために使用されます。
Func<out TResult>
対応するメソッド構造は次のとおりです。TResult Method(){...}
TResult は汎用の戻り値の型です
Func<in T, out TResult>
⇒ TResult Method(T a){...}
Func<in T1, in T2, out TResult>
⇒ TResult Method(T1 a, T2 b){...}
…
class Pragram
{
static void Main(string[] args)
{
Calc calc = new Calc();
Func<int, int, int> func1 = new Func<int, int, int>(calc.Add);
Func<int, int, int> func2 = new Func<int, int, int>(calc.Sub);
int a = 100;
int b = 200;
int res;
res = func1(a, b); // 调用calc.Add方法
Console.WriteLine(res); // 输出300
res = func2(a, b); // 调用calc.Sub方法
Console.WriteLine(res); // 输出-100
}
}
class Calc
{
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
}
カスタムデリゲート
代表団の宣言
デリゲートはクラスであり、クラスはデータ型であるため、デリゲートもデータ型です。
宣言の一般的な形式は次のとおりです。
访问修饰符 delegate 返回值类型 委托名称(参数列表);
// 声明委托
public delegate void SayHi(string name);
class Pragram
{
static void Main(string[] args)
{
SayHi sayHi = new SayHi(Hi);
sayHi.Invoke("张三");
}
static void Hi(string name)
{
Console.WriteLine("Hi, {0}", name);
}
}
デリゲートを使用する
一般に、デリゲートの正しい使用方法は回调函数
(コールバック関数とは) と模板方法
(テンプレート メソッドとは) です。
マルチキャスト委任
public delegate void SayHi(string name);
class Pragram
{
static void Main(string[] args)
{
SayHi sayHi1 = new SayHi(Hi1);
SayHi sayHi2 = new SayHi(Hi2);
SayHi sayHi3 = new SayHi(Hi3);
sayHi1 += sayHi2;
sayHi1 += sayHi3;
sayHi1.Invoke("张三"); // sayHi2和sayHi3同样会被调用
}
static void Hi1(string name)
{
Console.WriteLine("Hi1, {0}", name);
}
static void Hi2(string name)
{
Console.WriteLine("Hi2, {0}", name);
}
static void Hi3(string name)
{
Console.WriteLine("Hi3, {0}", name);
}
}
暗黙的な非同期呼び出し
BeginInvoke
暗黙的な非同期呼び出しは、委任されたメソッドを使用して行うことができます。
public delegate void SayHi(string name);
class Pragram
{
static void Main(string[] args)
{
SayHi sayHi1 = new SayHi(Hi1);
SayHi sayHi2 = new SayHi(Hi2);
SayHi sayHi3 = new SayHi(Hi3);
sayHi1.BeginInvoke("张三", null, null);
sayHi2.BeginInvoke("李四", null, null);
sayHi3.BeginInvoke("王五", null, null);
}
static void Hi1(string name)
{
Console.WriteLine("Hi1, {0}", name);
}
static void Hi2(string name)
{
Console.WriteLine("Hi2, {0}", name);
}
static void Hi3(string name)
{
Console.WriteLine("Hi3, {0}", name);
}
}