C#2.0介紹了一個新特性--匿名方法,允許開發者在線(inline)聲明自己的函數代碼而無須使用委托函數(delegate function)。C#3.0中提供了一個新特性--Lambda表達式,它提供了完成相同目標的更加簡潔的格式。讓我們在討論Lambda表達式以前仔細研究一下匿名方法。
匿名方法
假設你需要創建一個按鈕,當點擊它的時候更新ListBox裡的內容。在C#1.0和1.1裡,你要這樣做:
public MyForm() { listBox = new ListBox(...); textBox = new TextBox(...); addButton = new Button(...); addButton.Click += new EventHandler(AddClick); } void AddClick(object sender, EventArgs e) { listBox.Items.Add(textBox.Text); }
在C#2.0裡,你需要這樣做:
public MyForm() { listBox = new ListBox(...); textBox = new TextBox(...); addButton = new Button(...); addButton.Click += delegate { listBox.Items.Add(textBox.Text); };
就像你看到的一樣,你不必要特別的聲明一個新方法來將它連接到一個事件上。你可以在C#2.0裡使用匿名方法來完成同樣的工作。C#3.0裡介紹了一種更加簡單的格式,Lambda表達式,你可以直接使用"=>"來書寫你的表達式列表,後面跟上一個表達式或者語句塊。
Lambda表達式中的參數
Lambda表達式中的參數可以是顯式或者隱式類型的。在一個顯式類型參數列表裡,每個表達式的類型是顯式指定的。在一個隱式類型參數列表裡,類型是通過上下文推斷出來的:
(int x) => x + 1 // 顯式類型參數 (y,z) => return y * z; // 隱式類型參數
Lambda演算實例
下面的例子給出了兩種不同的方法來打印出一個list中長度為偶數的字符串。第一種方法AnonMethod使用了匿名方法,第二種LambdaExample則是通過Lambda演算實現:
// Program.cs using System; using System.Collections.Generic; using System.Text; using System.Query; using System.Xml.XLinq; using System.Data.DLinq; namespace LambdaExample { public delegate bool KeyValueFilter<K, V>(K key, V value); static class Program { static void Main(string[] args) { List<string> list = new List<string>(); list.Add("AA"); list.Add("ABC"); list.Add("DEFG"); list.Add("XYZ"); Console.WriteLine("Through Anonymous method"); AnonMethod(list); Console.WriteLine("Through Lambda expression"); LambdaExample(list); Dictionary<string, int> varClothes= new Dictionary<string,int>(); varClothes.Add("Jeans", 20); varClothes.Add("Shirts", 15); varClothes.Add("Pajamas", 9); varClothes.Add("Shoes", 9); var ClothesListShortage = varClothes.FilterBy((string name, int count) => name == "Shoes" && count < 10); // example of multiple parameters if(ClothesListShortage.Count > 0) Console.WriteLine("We are short of shoes"); Console.ReadLine(); } static void AnonMethod(List<string> list) { List<string> evenNumbers = list.FindAll(delegate(string i) { return (i.Length % 2) == 0; }); foreach (string evenNumber in evenNumbers) { Console.WriteLine(evenNumber); } } static void LambdaExample(List<string> list) { var evenNumbers = list.FindAll(i =>(i.Length % 2) == 0); // example of single parameter foreach(string i in evenNumbers) { Console.WriteLine(i); } } } public static class Extensions { public static Dictionary<K, V> FilterBy<K, V> (this Dictionary<K, V> items, KeyValueFilter<K, V> filter) { var result = new Dictionary<K, V>(); foreach(KeyValuePair<K, V> element in items) { if (filter(element.Key, element.Value)) result.Add(element.Key, element.Value); } return result; } } }
如果你安裝了Visual Studio 2005 and LinQ Preview,你可以使用編輯器來編譯程序。如果沒有的話,可以使用命令行方式: