今天將書中看的,自己想的寫出來,供大家參考,不足之處請指正。進入正題。
在C#1中開發web form常常會遇到使用事件,為每個事件創建一個事件處理方法,在將方法賦予給事件中,會使用new EventHandler(),不同的事件有各種不同的EventHandler的派生類的實例,因為我這裡使用的時Console App,原理是一樣的,且看
//定義一個委托 delegate void Printer(); static void Main(string[] args) { Printer p = new Printer(Print1); p += new Printer(Print2); p += new Printer(Print3); p.Invoke(); Console.ReadKey(); } static void Print1() { Console.WriteLine("print1"); } static void Print2() { Console.WriteLine("print2"); } static void Print3() { Console.WriteLine("print3"); }
可以看到每次給p委托一個方法時,都要new Printer(),參數為要傳入的方法,可以想象在不同的委托時,要用代碼顯式地創建各種委托,過於繁瑣。而在C#2中支持從方法組到一個兼容委托類型的隱式轉換,自己想當然的理解為C++中的復制構造函數,如Printer p = Print1其實就是調用了new Printer(Print1),代碼如下。
1 Printer p = Print1; 2 p += Print2; 3 p += Print3; 4 p.Invoke();
Printer p = Print1調用了Printer類的構造函數,而+=操作應該是Printer類型重載了+操作,用於兩個Printer類相加,而方法組實現隱式轉換,Print2和Print3隱式轉換為Printer類的實例,C#2這樣的操作減少了代碼的輸入,且更為直觀,如"我只是把一個方法給到了一個對象,讓它幫我執行,我才不管你要讓傳什麼樣的類型"。
對於第一點,可以理解為要給委托一個方法,用這個方法創建的委托可以是另一個委托的派生類,如所有事件處理的基類是EventHandler,當一個事件需要傳入一個方法,則可以使用這個方法來創建一個從EventHandler中派生的類的實例,不用事件我不會用代碼表示,請大牛告知。
對於第二點,委托定義返回類型中,如果返回類型有派生類,如在實現的方法中返回其派生類,則可以使用該方法創建委托。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
匿名方法,匿名方法使用delegate關鍵字,允許你指定一個內聯委托實例的操作,匿名方法返回一個委托的實例。
C#2中許多內建的泛型委托,如Action(T),Predicate<T>等等,則在實例化委托時可以使用匿名函數。如
1 Action<int> a = delegate (int x) { Console.WriteLine(x); }; 2 Predicate<bool> b = delegate (bool x) { return x == true; }; 3 a.Invoke(1); 4 b.Invoke(1 == 1); 5 a(2); 6 b(2 == 3);
請注意匿名方法返回一個委托實例。如果只是單純是只想處理一些無關於參數的事情,可以考慮省略參數。這讓我想到一點就是在程序出錯時,如果不記錄參數,可以直接打印"出錯了",而對於匿名函數,則可以省略參數。
1 System.Threading.Thread th = new System.Threading.Thread(delegate (object x) { }); 2 System.Threading.Thread th2 = new System.Threading.Thread(delegate() { });
其實上述的講法是錯的,其實很討厭一些話,寫了很多的東西,自己看得好像有點道理,然後突然告訴你"那些東西錯誤的觀點",這次我也來使用一下。
前面說過匿名函數返回一個委托的實例,我解理為匿名方法確實是一個方法,因為存在之前說過的隱式轉換(也就是C++中的復制構造函數,或者單參數的構造函數),它返回一個符合new System.Threading.Thread()中一個合適的參數類型,所以我覺得參數是不可省略的,書中就是可以省略,其實只是System.Threading.Thread有兩個重載版本而已,自己的想法,錯的請大牛們指正,小弟不勝感激。
請斧正。