C# Delegation (デリゲート) を理解しやすく、簡単な言葉で説明します
コミッションとは何ですか?
デリゲートは、まずデータ型です。構造体と同じように定義できます。デリゲート (Delegate) は、メソッドへの参照を保持する参照型変数です。参照は実行時に変更可能
委任の定義
//语法
delegate <return type> <delegate-name> <parameter list>
//实例
public delegate int MyDelegate (string s);
デリゲートをインスタンス化する (Delegate)
例えば:
public delegate void printString(string s);
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
端的に言えば、関数メソッドへのポインターに似ており、ポインターの型を定義するのと同じようにデリゲートの型を定義できます。
デリゲート型を定義するときは、パラメーターの型と関数の戻り値を指定する必要があります。デリゲート型を宣言したら、new キーワードを使用してデリゲート オブジェクトを作成し、特定のメソッドに関連付ける必要があります。デリゲートを作成するとき、新しいステートメントに渡されるパラメーターはメソッド呼び出しのように記述されますが、パラメーターはありません。
簡単な使用例
using System;
delegate int NumberChanger(int n);
namespace DelegateAppl
{
class TestDelegate
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args)
{
// 创建委托实例
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
// 使用委托对象调用方法
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
これは簡単な使い方の紹介であり、メインプログラム内でメソッドを直接呼び出すのと何ら変わりはなく、実際の使い方ではないことがわかります。
代表団の目的
マルチキャスト
デリゲート オブジェクトは、「+」演算子を使用して結合できます。マージされたデリゲートは、マージされた 2 つのデリゲートを呼び出します。同じタイプのデリゲートのみをマージできます。「-」演算子を使用すると、マージされたデリゲートからコンポーネント デリゲートを削除できます。
デリゲートのこの便利な機能を使用すると、デリゲートが呼び出されるときに呼び出されるメソッドの呼び出しリストを作成できます。これは委任されたマルチキャストと呼ばれ、マルチキャストとも呼ばれます。次のプログラムは委任されたマルチキャストを示しています。
static void Main(string[] args)
{
// 创建委托实例
NumberChanger nc;
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
nc = nc1;
nc += nc2;
// 调用多播
nc(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
キー: 委任の使用シナリオ
委任という名前が付けられているので、鮮やかな比喩を使用しましょう。会社では、上司/電話をかけてきた人は私に委任する/委任機能を有効にする必要はありませんが、Zhang San/func1 と Li Si/func2 の仕事を個人的に手配できます。 , 直接呼び出し, このとき、呼び出しのパラメータと呼び出しメソッドのコード (ループ呼び出しなど) を準備する必要がある場合があります. 上司
/呼び出し元は、関数を通じて Zhang San と Li Si の仕事を手配することもできます同時に、Zhang San/func1 と Li Si/func2 を一緒に指定することもできます。Work/ ±Multicastは、新しい従業員/メソッドで拡張することもできます。
これはクラス継承ポリモーフィズムに似ていますが、より柔軟です。デリゲート関数の I/activate は、呼び出したい関数とその特定の実装を知る必要はありません。必要なのは、呼び出し元によって指定されたパラメーターを使用することだけです。親クラスは、サブクラスがどのように実装するかを気にする必要はありません。サブタイプの割り当てを通じて、サブクラスによってオーバーライドされたメソッドを呼び出すことができます。
//委托
// 委托声明
public delegate void doSomething(string s);
//定义 回调函数 ,公司里的员工 张三,李四.............
public static void ZangSan(string a) {
Console.WriteLine("zhangsan"+a);
}
public static void LiSi(string a)
{
Console.WriteLine("lisi"+a);
}
/// <summary>
/// 中介,委托处理 ,使用此方法触发委托回调
/// </summary>
/// <param name="from">开始</param>
/// <param name="to">结束</param>
/// <param name="fb">委托引用</param>
private static void handleDelegate(int from, int to, doSomething ds)
{
//一些预处理 ,这样使用委托就比直接调用方便了
for (int val = from; val <= to; val++)
{
if (ds != null)
{
ds(val.ToString());
}
//ds?.Invoke(val); 简化版本调用
}
}
//主函数,调用者 老板
public void testDelegate()
{
//老板通过我/中介 给张三安排工作,
doSomething dsZhangSan = new doSomething(ZangSan);
//给张三李四 按顺序安排工作 //按序执行
doSomething dsLisi = new doSomething(LiSi);
doSomething ds = dsZhangSan + dsLisi;
//在调用的时可以给张三,李四传参数,这里在handleDelegate里面给了 ds(val.ToString());
handleDelegate(0, 3, ds);
//方法的返回值,参数必须完全一样,符合委托类型的定义
}
実行構造
コールバック関数の仕組み
私をサービスを提供する独立した仲介者と考えてください。上司/機能を実装する当事者である Zhang San/func1、Li Si/func2 ~~~ は同じ会社の出身です。協力する場合、上司は Zhang San または Li を指名します。 Si... 、特別な条件が発生したときに張三と李四を呼び出すだけなので、気にする必要はありません。
⑴定义一个回调函数;
⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。