在 2.0之前的 C#版本中,聲明委托的唯一方法是使用命名方法。 C# 2.0引入了匿名方法,而在 C# 3.0及更高版本中,Lambda表達式取代了匿名方法,作為編寫內聯代碼的首選方式。不過,本主題中有關匿名方法的信息同樣也適用於 Lambda表達式。有一種情況下,匿名方法提供了 Lambda表達式中所沒有的功能。可使用匿名方法來忽略參數列表。這意味著匿名方法可轉換為具有各種簽名的委托。這對於 Lambda表達式來說是不可能的。有關 lambda表達式的更多特定信息,參看MSDN
//匿名函數 var p1=new{Name="張三",Age=28}; var p2=new{Name="李四",Age=29}; var intArr=new[]{1,2,3,4,5};
首先我們來看一下上面這段代碼,比較簡單,和我們平時定義一個實例基本沒什麼區別,只是new後面沒有跟具體定義的類型;這裡我們使用new關鍵字調用匿名初始化器創建了一個匿名類型對象;匿名類型直接繼承自System.Object;匿名類型的成員是編譯器根據初始化器推斷而來的一些讀寫屬性。
這裡我們注意到C#匿名函數基本上是配合隱式類型var來使用的,而且定義的順序也是一定要注意,上面p1和p2初始化時定義的屬性名、類型和順序一致,因此編譯器認為他們是同一個類型,可以使用p1=p2這樣的賦值語句;特別是順序需要注意,如果初始化時名稱類型一致而順序不一致,則p1和p2就是兩個類型,如果使用p1=p2則編譯時會拋出錯誤:無法將類型“AnonymousType#1”隱式轉換為“AnonymousType#2” .定義匿名函數時還需要注意,不能用null賦初始值。
下面我們看例子
1 匿名函數與委托綁定
在事件中使用匿名方法
以下是一個定時器的小例子,我們常規的命名寫法如下:
class EventTest { public void Test() { System.Timers.Timer timersTimer =new System.Timers.Timer(); timersTimer.Enabled = true; timersTimer.Interval = 5000; timersTimer.Elapsed += newSystem.Timers.ElapsedEventHandler(timersTimer_Elapsed); Console.ReadLine(); } void timersTimer_Elapsed(object sender,System.Timers.ElapsedEventArgs e) { Console.WriteLine(System.DateTime.Now); } }
對於事件的處理我們需要單獨寫一個方法timersTimer_Elapsed,那麼如果使用匿名方法,則就可以省掉這個方法的定義,如下所示:
class EventTest { public void Test() { System.Timers.Timer timersTimer =new System.Timers.Timer(); timersTimer.Enabled = true; timersTimer.Interval = 5000; timersTimer.Elapsed += delegate(object sender,System.Timers.ElapsedEventArgs e) { Console.WriteLine(System.DateTime.Now); }; Console.ReadLine(); } }
也就是把方法的實現直接寫在內部。
2 匿名方法內部直接取得當前調用者的變量
使委托與匿名方法關聯。使委托與命名方法(DoWork)關聯。
delegate void Printer(string s); class TestClass { static void Main() { //1.使委托與匿名方法關聯. Printer p = delegate(string j) { System.Console.WriteLine(j); }; p("The delegate using the anonymous method is called."); //2.使委托與命名方法 (DoWork) 關聯。 p = new Printer(TestClass.DoWork); p("The delegate using the named method is called."); } static void DoWork(string k) { System.Console.WriteLine(k); } } /* Output: The delegate using the anonymous method is called. The delegate using the named method is called. */
當然代碼雖然看起來很少,實際上編譯器在編譯時還是會生成其他方法的。也就是說匿名方法可以減少代碼量,
節省開發時間,但是對於性能方法沒有什麼提升的。
小結:通過實例認識到,匿名函數可以簡化代碼,但是這個度還要根據自己的水平來判定,不然出了錯誤真是一個
很難的點。其次匿名函數在編譯中並沒有簡化代碼量,在生成時後台會生成一個類以及類似的方法。但是你若要
將代碼傳遞為委托參數,創建匿名方法則是唯一的方法。下篇Lambda表達式