前面的文章中,大家已經對C#3.0的新特性有了一個基本的了解,比如強大的LINQ語言和擴展方法的應用,今天給大家介紹的是C#3.0中添加的另一個重要的新特性:匿名方法。
1. 匿名溯源
匿名的歷史可謂由來已久,在C#2.0中匿名方法就已經大量使用在委托(delegate)的應用場景中。下面我舉幾個例子大家可以簡單回顧一下:
1) 當我們需要調用一個回調方法時,不需要構建委托對象,只需要將回調方法名傳入,CLR會替我們完成委托對象的創建工作。
//example 1
public static void CallBackWithoutANewDelegateObject()
{
//這裡QueueUserWorkItem方法需要一個委托作為參數,
//但我們僅僅傳遞給回調方法名,CLR可以自動為我們構造出委托對象的代碼
ThreadPool.QueueUserWorkItem(SomeAsyncTask, 5);
}
private static void SomeAsyncTask(object o)
{
Console.WriteLine(o);
}
這個例子中我們沒有構造出任何委托對象,而僅僅傳遞了回調方法名稱,CLR幫我構建了創建委托對象的代碼。
2)我們甚至不用顯式定義回調方法,只需要使用delegate關鍵字內聯的寫出方法代碼執行調用。
//example 2
public static void CallbackWithoutNewingADelegateObject()
{
//我們在這兒以內聯形式寫出回調方法體,而沒有定義任何的回調方法
ThreadPool.QueueUserWorkItem(
delegate(object o) { Console.WriteLine(o); },
5);
}
這個例子中我們並沒有定義上面的方法SomeAsyncTask,而是內聯寫出方法體。
3)我們甚至可以不寫出調用方法的參數,CLR也會為我們生成正確的委托對象。
//example 3
this.BT_LOGIN.Click +=
delegate { MessageBox.Show("Button Login has been clicked!"); };
這是匿名方法最常見的使用場景,即在添加一個控件的事件處理函數時直接使用delegate寫出方法代碼而不需要另外定義方法函數。當我們的事件處理函數很簡短時(比如上面的代碼我們僅僅彈出一個對話框顯示一條信息而已。)我們就可以使用這種方法,如果另外定義一個函數就會顯得很累贅。而且方法的參數也可以省略(比如這裡的Object sender, EventArgs e)
2. C#3.0中的匿名方法
1) 隱式類型變量 (Implicitly typed local variables)
var var1 = 1;
var var2 = 2;
var var3 = var1 + var2;
var var4 = "I'm a string.";
這裡我們可以看到我們並沒有指定變量的類型(int , string, …),但編譯器會幫我們完成這一點。熟悉腳本語言的朋友們可能會對此次語法感到驚喜,但要注意的是,C#仍然是強類型的語言,所有類型都會在編譯期確定,而不是像腳本那樣等到運行時,下面這張圖很清楚的說明了這一點: