標籤:style blog http color os io art cti
一、委託:
委託給我的感覺就是一個種類型,可以讓方法更具物件導向的特性——你看,其實我也沒說明白,因為我也不大理解。還是一步步往下學吧。
具體來說,委託就是一個類似下面的這種東西:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Collections;namespace ConsoleTestCsharp{ class Program { delegate double ProcessDelegate(double param1, double param2); static double Multiply(double param1, double param2) { return param1 * param2; } static double Divide(double param1, double param2) { return param1 / param2; } static void Main(string[] args) { ProcessDelegate process; string input = "M"; if (input == "M") process = new ProcessDelegate(Multiply); else process = new ProcessDelegate(Divide); Console.WriteLine("Result: {0}", process(2, 3)); } }}
View Code
給我的感覺反正就是很吊的樣子,delegate定義了一個委託類型,注意是類型不是對象,就像class關鍵字定義了一個類型一樣。這個類型將來需要new來進行執行個體化——這也類似於class。執行個體化的過程還需要給其傳遞一個方法。貌似,委託其實定義了一種方法範式:方法接受的參數是什麼樣子,傳回型別是什麼樣子。至於方法可以做什麼動作、完成什麼功能,委託類型並不關心,只要你這個方法跟我這個委託類型的方法外觀長得一樣,你將來就可以執行個體化我。一旦我——委託類型得到執行個體化了,我就可以像方法一樣被調用了。基本就是這樣了,更深刻的理解我也沒有。
二、事件:
訂閱事件——媽的,關於事件,似乎只在C#裡聽到訂閱這種說法,牛逼哄哄的,讓我這種菜鳥又得接受一個新詞彙,訂閱的意思就是:“訂閱一個事件的含義是提供代碼,在事件發生時執行這些代碼,它們稱為事件處理常式。”引號引著,因為這是書中原話。
一個事件可以有多個處理常式——即被多次訂閱,事件發生時這些代碼都會依次執行。處理常式,就是那個處理函數應該長什麼樣子——參數是什麼,傳回型別是什麼——由事件相關的委託決定。事件相關的委託是什麼毛意思呢,我也不明白,先往下看吧。
class Program { static int counter = 0; static string displayString = "This string will appear one letter at a time. "; static void Main(string[] args) { Timer myTimer = new Timer(100); myTimer.Elapsed += WriteChar; myTimer.Start(); Console.ReadKey(); } static void WriteChar(object source, ElapsedEventArgs e) { Console.Write(displayString[counter++ % displayString.Length]); } }
View Code
代碼定義了一個Timer,每隔100毫秒觸發一次Elapsed事件。然後你搞一個方法處理這個事件(訂閱事件),事件發生時調用你的方法,你方法到底應該長什麼樣子才符合其要求呢。不妨看下Elapsed到底是什麼東西。按F12,你會發現在Timer類裡,有這樣一行:
public event ElapsedEventHandler Elapsed;
接著F12,會發現在System.Timers命名空間裡有這樣一行:
public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e);
要知道,ElapsedEventHandler是一種類型,它是直接定義在命名空間裡的,而Elapsed則是作為Timer的類成員定義的,是ElapsedEventHandler這種類型的一個執行個體(嚴格說來是一個引用)。所以,Elapsed其實是一個委派物件,不過由於它又是用event來限定的,所以跟上邊說的委託又不太一樣,至於底層到底是什麼關係,我是沒能力往下挖掘了。反正,可以確定的是:ElapsedEventHandler是一個委託類型無疑,當年這個委託類型是怎麼定義的,以後你在訂閱這個事件的時候就該,也只能傳遞某些格式的方法。顯然WriteChar是這個符合要求的:
static void WriteChar(object source, ElapsedEventArgs e)
{
Console.Write(displayString[counter++ % displayString.Length]);
}
其實添加一個事件處理常式(訂閱)最正宗的做法應該是這樣:
myTimer.Elapsed += new ElapsedEventHandler(WriteChar);
可讀性要強一點。上面這行代碼更加鞏固了我的感覺:事件其實就是一個委託執行個體,訂閱事件就是在給這個執行個體賦值為相應的委託執行個體。當然,委託類型本身的定義則規定了你在new一個委託的時候應該傳遞什麼樣子的方法。媽的,感覺微軟的事件機制真有些脫褲子放屁的感覺,我作為一個菜鳥說這些氣話也理所當然,因為我還沒有體會到大師們作此設計的意義所在,等以後體會到了,再回來道個歉——如果我還記得的話。
三、自訂事件(以後再說,估計短期內也用不到)
四、匿名方法:
匿名方法的目的就是為了簡化委託的執行個體化方式:
myConnection1.MessageArrived +=
delegate(Connection source, MessageArrivedEventArgs e)
{
Console.WriteLine("Message arrived from: {0}", source.Name);
Console.WriteLine("Message Text: {0}", e.Message);
};