本篇博客和大家分享一下C#中的委托。
我們先思考這麼一個問題,如果我現在想寫一個Person類,定義如下:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void ZhuangBi()
{
//第一步,找到話題
//第二步,找到一個能夠聊天的人
Console.WriteLine( "I am newbility");
}
}
為了使程序更加靈活,我不想在ZhuangBi這個方法中寫具體的實現,那麼問題來了,第一步和第二步怎麼實現?我們可以抽象出一個接口,然後依賴注入,不過這不在本篇討論的范圍內。我們能不能給ZhuangBi這個方法添加兩個參數,這兩個參數分別指向一個方法,也就是說,外界調用這個方法時,會傳進來兩個方法,一個方法負責找到話題,另一個方法負責找到能聊天的人。可是,怎麼才能把方法當成參數來傳遞呢?參數的類型是什麼呢?
在.net 的世界裡,委托(delegate)為了解決這個問題誕生了。委托是一種類型,能夠指向一個方法。委托更准確的定義是:委托是表示對具有特定參數列表和返回類型的方法的引用的類型。
為了解決上面的問題,我們來定義一個委托,為了簡單起見,參數列表和返回值都為空
public delegate void MyDelegate();
然後改造一下ZhuangBi這個方法,改造後的代碼如下
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void ZhuangBi(MyDelegate findTopic, MyDelegate findPerson)
{
//首先,找到話題
findTopic();
//然後,找到一個能夠聊天的人
findPerson();
Console.WriteLine("I am newbility");
}
}
最後我們再寫一個類,來調用這個Person類,並傳遞兩個方法過來
class Program
{
static void Main(string[] args)
{
Person p = new Person();
MyDelegate delegate_FindTopic = FindTopic;
MyDelegate delegate_FindPersonToTalk = FindPersonToTalk;
p.ZhuangBi(delegate_FindTopic, delegate_FindPersonToTalk);
}
static void FindTopic()
{
Console.WriteLine("MongoDB is not too bad");
}
static void FindPersonToTalk()
{
Console.WriteLine("find a geek");
}
}
運行結果如下
MongoDB is not too bad
find a geek
I am newbility
在很多時候,我們可以使用系統已經定義好的委托,System.Action是參數列表和返回值都為空的委托,定義如下
public delegate void Action();
Func<> 是一個范型委托,有17個重載,最多可以定義16個范型參數。這兩個委托應該能滿足幾乎所有的應用場景了。