委托是什么?
委托首先是一個數(shù)據(jù)類型,我們可以像定義結(jié)構(gòu)體一樣定義一個委托類型,委托(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);
說白了就是類似指向函數(shù)方法的指針,我們可以類似定義指針類型一樣,定義委托的類型
在定義委托類型時要指定函數(shù)的參數(shù)類型和返回值,一旦聲明了委托類型,委托對象必須使用 new 關(guān)鍵字來創(chuàng)建,且與一個特定的方法有關(guān)。當(dāng)創(chuàng)建委托時,傳遞到 new 語句的參數(shù)就像方法調(diào)用一樣書寫,但是不帶有參數(shù)。
簡單用法實例
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)
{
// 創(chuàng)建委托實例
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
// 使用委托對象調(diào)用方法
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
這只是簡單的用法介紹,可以看出 這和在主程序里直接調(diào)用方法沒啥區(qū)別,并不是實際的用法。
委托的用途
多播
委托對象可使用 “+” 運算符進行合并。一個合并委托調(diào)用它所合并的兩個委托。只有相同類型的委托可被合并。"-" 運算符可用于從合并的委托中移除組件委托。
使用委托的這個有用的特點,您可以創(chuàng)建一個委托被調(diào)用時要調(diào)用的方法的調(diào)用列表。這被稱為委托的 多播(multicasting),也叫組播。下面的程序演示了委托的多播
static void Main(string[] args)
{
// 創(chuàng)建委托實例
NumberChanger nc;
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
nc = nc1;
nc += nc2;
// 調(diào)用多播
nc(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
關(guān)鍵: 委托的使用場景
委托,故名思意,咱們用一個形象的比喻,公司里 ,老板/調(diào)用者 ,可以不用委托我/激活委托函數(shù),親自去給張三/func1,李四/func2 安排工作,就是直接調(diào)用,這時或許要準備調(diào)用的參數(shù)和調(diào)用方式的代碼 比如循環(huán)調(diào)用,
老板/調(diào)用者 還可以通過我/激活委托的函數(shù) 去安排張三李四的工作,同時也可以指定張三/func1,李四/func2 一起工作/±多播,也可以拓展新的員工/方法。
和類的繼承多態(tài)有異曲同工之妙,不過更加靈活,我/激活委托函數(shù) 不需要知道自己要調(diào)用什么函數(shù)以及具體實現(xiàn),只管用調(diào)用者給的參數(shù)就行了 ,父類不用管子類如何實現(xiàn)的,通過子類型的賦值,就能調(diào)用子類重寫的方法。
//委托
// 委托聲明
public delegate void doSomething(string s);
//定義 回調(diào)函數(shù) ,公司里的員工 張三,李四.............
public static void ZangSan(string a) {
Console.WriteLine("zhangsan"+a);
}
public static void LiSi(string a)
{
Console.WriteLine("lisi"+a);
}
/// <summary>
/// 中介,委托處理 ,使用此方法觸發(fā)委托回調(diào)
/// </summary>
/// <param name="from">開始</param>
/// <param name="to">結(jié)束</param>
/// <param name="fb">委托引用</param>
private static void handleDelegate(int from, int to, doSomething ds)
{
//一些預(yù)處理 ,這樣使用委托就比直接調(diào)用方便了
for (int val = from; val <= to; val++)
{
if (ds != null)
{
ds(val.ToString());
}
//ds?.Invoke(val); 簡化版本調(diào)用
}
}
//主函數(shù),調(diào)用者 老板
public void testDelegate()
{ //老板通過我/中介 給張三安排工作,
doSomething dsZhangSan = new doSomething(ZangSan);
//給張三李四 按順序安排工作 //按序執(zhí)行
doSomething dsLisi = new doSomething(LiSi);
doSomething ds = dsZhangSan + dsLisi;
//在調(diào)用的時可以給張三,李四傳參數(shù),這里在handleDelegate里面給了 ds(val.ToString());
handleDelegate(0, 3, ds);
//方法的返回值,參數(shù)必須完全一樣,符合委托類型的定義
}
執(zhí)行結(jié)構(gòu)
文章來源:http://www.zghlxwxcb.cn/news/detail-432912.html
回調(diào)函數(shù)的機制
把我想象成是獨立的提供服務(wù)的中介,而老板/函數(shù)實現(xiàn)的一方, 張三/func1,李四/func2 ~~~是一個公司的,合作時,老板指定張三或是李四… , 而我不需要關(guān)心,我只是在特點條件發(fā)生時去調(diào)用張三李四就行了文章來源地址http://www.zghlxwxcb.cn/news/detail-432912.html
⑴定義一個回調(diào)函數(shù);
⑵提供函數(shù)實現(xiàn)的一方在初始化的時候,將回調(diào)函數(shù)的函數(shù)指針注冊給調(diào)用者;
⑶當(dāng)特定的事件或條件發(fā)生的時候,調(diào)用者使用函數(shù)指針調(diào)用回調(diào)函數(shù)對事件進行處理。
到了這里,關(guān)于理解C#委托(Delegate)通俗易懂,深入淺出的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!