4.C#編程指南-匿名函數


匿名函數是一個“內聯”語句或表達式,可在需要委托類型的任何地方使用。可以使用匿名函數來初始化命名委托,或傳遞命名委托(而不是命名委托類型)作為方法參數。

共有兩種匿名函數:

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.
*/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM