在C#2.0引入匿名方法之前,聲明委托的唯一方法就是使用命名方法,C#2.0之後的C#3.0中開始引入了Lambda表達式取代了匿名方法。
匿名方法
要說Lambda必然離不開匿名方法,實際上,Lambda的本質就是一個匿名方法,上代碼
class Program { delegate void SayHello(string name); public static void Main(string[] args) { SayHello sh1 = HelloMethod; SayHello sh2 = delegate (string name)//匿名方法 { Console.WriteLine("Hello:" + name); }; sh1("jiming1"); sh2("jiming2"); Console.Read(); } public static void HelloMethod(string name) { Console.WriteLine("Hello:" + name); } }
上述代碼中,首先定義了一個委托SayHello,注冊到改委托的方法需要有一個string類型的參數,第一個委托對象sh1直接使用的是命名方法HelloMethod,第二個委托對象sh2使用的就是匿名方法.
Lambda表達式
lambda運算符:所有的lambda表達式都是用新的lambda運算符 " => ",可以叫他,“轉到”或者 “成為”。運算符將表達式分為兩部分,左邊指定輸入參數,右邊是lambda的主體。參數的個數可以是0、1或多個,只有當輸入參數是1個時,Lambda表達式左邊的小闊海才可以省略
示例:
public static void Main(string[] args) { Action action = new Action(() => Console.WriteLine("0參數Lambda")); action.Invoke(); Console.Read(); }
分析:上述代碼中,他輸入的參數是0,方法主體打印"0參數Lambda"
示例2:
public static void Main(string[] args) { Func<int,int> func = new Func<int,int>(m=>m*2); Console.WriteLine(func.Invoke(3)); Console.Read(); }
上述Lambda表達式的輸入參數省略了一對小括弧,它與“(m)=>m*2”Lambda表達式是等效的。這裡還包含另外一個C#的語法糖,由於方法體中只有一句話,所以,可以省略{},甚至省略了return,實際上,上述代碼的全部寫法應該是:
public static void Main(string[] args) { Func<int, int> func = new Func<int, int>((m) =>{ return m * 2; }); Console.WriteLine(func.Invoke(3)); Console.Read(); }
示例3:
public static void Main(string[] args) { Action<int, int> action = new Action<int, int>((m,n)=> { int result = m * n; Console.WriteLine(result); }); action.Invoke(3, 2); Console.Read(); }
上述代碼中左邊是兩個參數,m\n,方法體中是計算m*n的結果,然後打印出來,由於方法體中是多行,因此,不能省略{}
總結:
1.(x, y) => x * y //多參數,隱式類型=> 表達式 2.x => x * 5 //單參數, 隱式類型=>表達式 3.x => { return x * 5; } //單參數,隱式類型=>語句塊 4.(int x) => x * 5 //單參數,顯式類型=>表達式 5.(int x) => { return x * 5; } //單參數,顯式類型=>語句塊 6.() => Console.WriteLine() //無參數
使用Lambda表達式,可以方便快速的編寫代碼,一些不復用的方法完全可以使用Lambda表達式來寫,這樣既提高了代碼的可讀性,也減少了代碼量提高可維護性。
同時Lambda右邊方法體內的代碼塊能夠訪問Lambda所在方法提所定義的局部變量,這樣能夠較少參數的定義和傳遞。
public static void Main(string[] args) { string name = "jiming"; Func<int, int,int> func = new Func<int, int,int>((m,n)=> { int result = m * n; Console.WriteLine(result); Console.WriteLine(name); return result; }); func.Invoke(3, 3); Console.Read(); }
如上述代碼,name變量是定義在Main方法中的,如果不使用Lambda,使用命名方法的話,在命名方法中使用name我需要定義一個變量之後傳遞進入,而使用Lambda後很方便的就能夠訪問name變量了