匿名函數是一個“內聯”語句或表達式,可在需要委托類型的任何地方使用。可以使用匿名函數來初始化命名委托,或傳遞命名委托(而不是命名委托類型)作為方法參數。
共有兩種匿名函數:
1.Lambda表達式
2.匿名方法
C#委托的發展
View Code
class Test { delegate void TestDelegate(string s); static void M(string s) { Console.WriteLine(s); } static void Main(string[] args) { TestDelegate testDelA = new TestDelegate(M); TestDelegate testDelB = delegate(string s) {Console.WriteLine(s); }; TestDelegate testDelC = (x) => { Console.WriteLine(x); }; testDelA("Hello. My name is M and I write lines."); testDelB("That's nothing. I'm anonymous and "); testDelC("I'm a famous author."); } } /* Output: Hello. My name is M and I write lines. That's nothing. I'm anonymous and I'm a famous author. */
Lambda表達式
"Lambda表達式"是一個匿名函數,它可以包含表達式和語句,並且可用於創建委托或表達式樹類型。
所有Lambda表達式都使用Lambda運算符=>,該運算符讀為“goes to”。該Lambda運算符的左邊是輸入參數(如果有),右邊則包含表達式或語句塊。
=>運算符具有與賦值運算符(=)相同的優先級,並且是右結合運算符。
Lambda在基於方法的LINQ查詢中用作標准查詢運算方法(如Where)的參數。
使用基於方法的語法在Enumerable類中調用Where方法時,參數是委托類型System.Func(Of T,TResult)。使用Lambda表達式創建委托最為方便。
在is或as運算符的左側不允許使用Lambda。
1.基本形式:
(input parameters) => expression
2.只有在Lambda有一個輸入參數時,括號才是可選的;否則括號是必需的。兩個或更多輸入參數由括號中的逗號分隔:
(x,y) => x == y
3.有時,編譯器難於或無法推斷輸入類型。如果出現這種情況,您可以按以下方式顯式指定類型:
(int x,string s) => s.Length > x
4.使用空括號指定零個輸入參數:
() => SomeMethod()
Lambda語句
Lambda語句與Lambda表達式類似,只是語句在大括號中:
(input parameters) => {statement;}
Lambda語句的主體可以包含任意數量的語句;但是,實際上通常不會多於兩個或三個語句。
帶有標准查詢運算符的Lambda
許多標准查詢運算符都具有輸入參數,其類型是泛型委托的Func(Of T,TResult)系列的其中之一。Func(Of T,TResult)委托使用類型參數定義輸入參數的數目和類型,以及委托的返回類型。
例如,假設有以下委托類型:
public delegate TResult Func<TArg0,TResult>(TArg0 arg0)
可以將委托實例化為Func<int,bool> myFunc,其中int是輸入參數,bool是返回值。始終在最后一個類型參數中指定返回值。Func<int,string,bool>定義包含兩個參數(int和string)且返回類型為bool的委托。
在調用下面的Func委托時,該委托將返回true或false以指定輸入參數是否等於5:
Func<int,bool> myFunc = x => x == 5; bool result = myFunc(4); //returns false of course
匿名方法
在2.0之前的C#版本中,聲明委托的唯一方法是使用命名方法。C#2.0引入了匿名方法,而在C#3.0及更高版本中,Lambda表達式取代了匿名方法,作為編寫內聯代碼的首選方式。有一種情況下,匿名方法提供了Lambda表達式中所沒有的功能。您可使用匿名方法來忽略參數列表。這意味着匿名方法可以轉換為具有各種簽名的委托。這對於Lambda表達式來說是不可能的。
要將代碼塊傳遞為委托參數,創建匿名方法則是唯一的方法。
//例1 button1.Click += delegate(System.Object o, System.EventArgs e) { System.Windows.Forms.MessageBox.Show("Click!"); }; //例2 delegatevoid Del(int x); Del d = delegate(int k) { /* ... */ };
下面的示例演示實例化委托的兩種方法:
1.使委托與匿名方法關聯。
2.使委托與命名方法(DoWork)關聯。
View Code
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. */
