Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)
Delegate,Action,Func,匿名方法,匿名委托,事件 (轉載)
?
一、委托Delegate一般的方法(Method)中,我們的參數總是string,int,DateTime...這些基本的數據類型(或者沒有參數),比如
publicvoid HelloWorld(){
??? Console.WriteLine("Hello World!");
}
publicvoid HelloWorld(string name)
{
??? Console.WriteLine("Hello ,{0}!", name);
}
但是有些時候,我們希望把一個方法本身當做參數傳遞給另一個方法,比如
myObject.callMethod(HelloWorld);
在沒有委托之前,這是一件極困難的事情,委托出現以后,這就是一件很容易的事情了,簡單點講:委托就是一種能把方法當做參數來使用的類型--當然這個定義跟官方的解釋比起來極不嚴密,但易于理解
要點:
1.委托是一種類型(跟string,int,double...一樣是.net的一種基本類型)
2.委托的定義必須與最終被調用的方法保持簽名一致
比如:下面代碼中的
delegate void D1(); 與 static void HelloWorld1(),我們拋開前面的類型關鍵字delegate與static,他們的簽名都是void X()
void D2(string myName);與void HelloWorld2(string name); void HelloWorld3(string name);它們的簽名格式都是 void X(string Y)
3.委托的好處之一在于可以保持簽名格式不變的情況下,動態調用不同的處理邏輯(即不同的方法)
想想系統控件中的Button類,系統并不知道按鈕按下去時到底會執行怎么樣的邏輯(點擊后的處理,每個項目可能都不一樣,完全由需求決定),但是我們知道每個Button都有一個Click(object sender, EventArgs e)這樣的東東,沒錯,就是委托(當然封裝成了另一種衍生類型event),就是這種設計保證了統一的格式,不管你實際開發中想如何處理點擊后的邏輯,只要按這個統一的簽名來就行了
完整代碼演示:
namespace ActionStudy
{
??? class Program
??? {
??????
??????? delegatevoid D1();
??????? delegatevoid D2(string myName);
??????? staticvoid Main(string[] args)
??????? {
??????????? D1 d1 =new D1(HelloWorld1);
??????????? d1();
??????????? D2 d2 =new D2(HelloWorld2);
??????????? d2("Jimmy");
??????????? d2 =new D2(HelloWorld3);
??????????? d2("楊俊明");???????????
??????????? Console.Read();
??????? }
??????? staticvoid HelloWorld1()
??????? {
??????????? Console.WriteLine("Hello World!");
??????? }
??????? staticvoid HelloWorld2(string name)
??????? {
??????????? Console.WriteLine("Hello,{0}!", name);
??????? }
??????? staticvoid HelloWorld3(string name)
??????? {
??????????? Console.WriteLine("你好,{0}!", name);
??????? }
??? }
}
二 、匿名方法(.net2.0開始支持)
在“一、委托Delegate”的演示代碼中,我們看到委托調用方法前,至少得先定義一個簽名相同的方法,然后才能由委托調用(哪怕是只有一行代碼的方法),好象有點煩哦,想偷懶,ok,沒問題
using System;namespace ActionStudy
{
??? class Program
??? {
??????? delegatevoid D1();
??????? delegatevoid D2(string myName);
??????? staticvoid Main(string[] args)
??????? {
??????????? D1 d1 =delegate
??????????? {
??????????????? Console.WriteLine("Hello World!");
??????????? };
??????????? d1();
??????????? D2 d2 =delegate(string name)
??????????? {
??????????????? Console.WriteLine("Hello,{0}!", name);
??????????? };
??????????? d2("Jimmy");
??????????? d2 =delegate(string name)
??????????? {
??????????????? Console.WriteLine("你好,{0}!", name);
??????????? };
??????????? d2("楊俊明");
??????????? Console.Read();
??????? }
??? }
}
運行效果完全相同,只是省去了方法的單獨定義部分
到了.net 3.0這種偷懶的作風更夸張,看下面的代碼(利用了Lambda表達式)
using System;namespace ActionStudy
{
??? class Program
??? {
??????? delegatevoid D1();
??????? delegatevoid D2(string myName);
??????? staticvoid Main(string[] args)
??????? {??????????
??????????? D1 d1 = () => { Console.WriteLine("Hello World!"); };
??????????? d1();
??????????? D2 d2 = (string name) => { Console.WriteLine("Hello,{0}!", name); };
??????????? d2("Jimmy");
??????????? d2 = (string name) => { Console.WriteLine("你好,{0}!", name); };
??????????? d2("楊俊明");
??????????? Console.Read();
??????? }
??? }
}
運行效果仍然沒變,初次接觸者可能感覺很怪,其實我也覺得怪,不過很多大牛們都喜歡這樣用,所以至少還是要能看得懂,否則別人會說"你 Out了" :)
三、Action
Action的本質就是委托,看它的定義:
namespace System{
??? // 摘要:
??? //???? Encapsulates a method that takes no parameters and does not return a value.
??? publicdelegatevoid Action();
}
namespace System
{
??? // 摘要:
??? //???? Encapsulates a method that takes a single parameter and does not return a
??? //???? value.
??? //
??? // 參數:
??? //?? obj:
??? //???? The parameter of the method that this delegate encapsulates.
??? //
??? // 類型參數:
??? //?? T:
??? //???? The type of the parameter of the method that this delegate encapsulates.
??? publicdelegatevoid Action<T>(T obj);
}
當然,還有Action<T1,T2>乃至Action<T1,T2,T3,T4>參數個數從2到4的類型,不過定義都差不多
簡單點講,Action是參數從0到4,返回類型為void(即沒有返回值)的委托
using System;namespace ActionStudy
{
??? class Program
??? {
??????? static Action A1;
??????? static Action<string> A2;
??????
??????? staticvoid Main(string[] args)
??????? {
??????????? A1 =new Action(HelloWorld1);
??????????? A1();
??????????? A2 =new Action<string>(HelloWorld2);
??????????? A2("Jimmy");
??????????? A2 = (string name) => { Console.WriteLine("你好,{0}!", name); };
??????????? A2("楊俊明");
??????????? A2 =delegate(string name) { Console.WriteLine("我就是委托,{0} 你說對嗎?", name); };
??????????? A2("菩提樹下的楊過");?????????
??????????? Console.Read();
??????? }
??????? staticvoid HelloWorld1()
??????? {
??????????? Console.WriteLine("Hello World!");
??????? }
??????? staticvoid HelloWorld2(string name)
??????? {
??????????? Console.WriteLine("Hello,{0}!", name);
??????? }
??????
??? }
??
}
四、Func
Func其實也是一個"托"兒,呵呵,不過這個委托是有返回值的??聪露x就知道了:
namespace System{
??? // 摘要:
??? //???? Encapsulates a method that has no parameters and returns a value of the type
??? //???? specified by the TResult parameter.
??? //
??? // 類型參數:
??? //?? TResult:
??? //???? The type of the return value of the method that this delegate encapsulates.
??? //
??? // 返回結果:
??? //???? The return value of the method that this delegate encapsulates.
??? publicdelegate TResult Func<TResult>();
}
namespace System
{
??? // 摘要:
??? //???? Encapsulates a method that has one parameter and returns a value of the type
??? //???? specified by the TResult parameter.
??? //
??? // 參數:
??? //?? arg:
??? //???? The parameter of the method that this delegate encapsulates.
??? //
??? // 類型參數:
??? //?? T:
??? //???? The type of the parameter of the method that this delegate encapsulates.
??? //
??? //?? TResult:
??? //???? The type of the return value of the method that this delegate encapsulates.
??? //
??? // 返回結果:
??? //???? The return value of the method that this delegate encapsulates.
??? publicdelegate TResult Func<T, TResult>(T arg);
}
同Action類似,Func的參數從1到5個,有5個不同的重載版本
代碼:
namespace ActionStudy
{
??? class Program
??? {
???????????????
??????? static Func<string> F;
??????? static Func<DateTime, string> F2;?????
??????? staticvoid Main(string[] args)
??????? {
??????????? F =new Func<string>(HelloWorld1);
??????????? Console.WriteLine(F());
??????????? F2 =new Func<DateTime, string>(HelloWorld2);
??????????? Console.WriteLine(F2(DateTime.Now));
??????????? Console.Read();
??????? }
??????? staticstring HelloWorld1()
??????? {
??????????? return"Hello World!";
??????? }
??????? staticstring HelloWorld2(DateTime time)
??????? {
??????????? returnstring.Format("Hello World,the time is {0}.", time);
??????? }
??????
??? }??
}
五、匿名委托
ok,如果你沒有暈的話,再來看一下匿名委托,其實這也是一種偷懶的小伎倆而已
看代碼說話:
//F = new Func<string>(HelloWorld1);
其實也可以簡寫成這樣:
F = HelloWorld1;? ????????
//F2 = new Func<DateTime, string>(HelloWorld2);
其實也可以簡寫成這樣
F2 = HelloWorld2;
方法直接賦值給委托,這二個類型不同吧???
沒錯,你會發現編譯一樣能通過,系統在編譯時在背后自動幫我們加上了類似 “= new Func<...>”的東東,所以我們能偷懶一下下,這個就是匿名委托。
如果你細心的話,會發現我們在定義Button的Click處理事件時,通常是這樣的:
this.button1.Click += new EventHandler(button1_Click);
但有時候我們也可以寫成這樣:
this.button1.Click += button1_Click;
這其實就是匿名委托的應用.
六、事件event
其實,這...還是個托兒!
我們來看下按鈕Click事件的定義
// 摘要://???? Occurs when the control is clicked.
publicevent EventHandler Click;
繼續刨根問底,查看EventHandler的定義:
using System.Runtime.InteropServices;namespace System
{
??? // 摘要:
??? //???? Represents the method that will handle an event that has no event data.
??? //
??? // 參數:
??? //?? sender:
??? //???? The source of the event.
??? //
??? //?? e:
??? //???? An System.EventArgs that contains no event data.
??? [Serializable]
??? [ComVisible(true)]
??? publicdelegatevoid EventHandler(object sender, EventArgs e);
}
?
看到了吧,就是委托!
轉載請注明來自菩提樹下的楊過http://www.cnblogs.com/yjmyzz/archive/2009/11/23/1608818.html
轉載于:https://www.cnblogs.com/xishi/p/3653235.html
總結
以上是生活随笔為你收集整理的Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python的subprocess子进程
- 下一篇: Fire Net