簡體   English   中英

C#中的lambda表達式?

[英]lambda expressions in C#?

我是新手,有人可以解釋(以下代碼)的意義,或者可能鏈接到一些關於lambda表達式的有用信息? 我在測試中遇到以下代碼,我想知道為什么有人會這樣做:

foo.MyEvent += (o, e) => { fCount++; Console.WriteLine(fCount); };

foo.MyEvent -= (o, e) => { fCount++; Console.WriteLine(fCount); };

我的直覺告訴我這是一件簡單而不是錯誤的事情,但我對這些表達方式知之甚少,無法理解為什么要這樣做。

lambda表達式(o, e) => { fCount++; Console.WriteLine(fCount); } (o, e) => { fCount++; Console.WriteLine(fCount); } (o, e) => { fCount++; Console.WriteLine(fCount); }被解釋為采用兩個參數匿名方法 o, e (其類型與用於委托類型被推斷MyEvent並返回void ,它捕獲fCount在封閉方法的主體變量(如果它是一個局部變量)。 +=運算符將為事件訂閱匿名方法,並且-=取消訂閱事件中的委托。


更新(re:關於委托實例相等性的問題):

重要的是要知道嘗試取消訂閱這樣的事件並不是一個好主意。 語言規范允許,但不要求第二行中的委托等於第一行中的委托。 也就是說,允許編譯器將兩個匿名函數體視為相同的函數,或者它是否相同(因為匿名函數體在語義上是相同的,並且捕獲的變量集也是相同的)。 即使它在編譯器中按預期工作,它也可能在下一個版本中中斷。 引用C#語言規范:

C#語言規范(第7.9.8節委托相等運算符):

通過評估具有相同(可能為空)的捕獲外部變量實例集的語義相同的匿名函數表達式而產生的調用列表條目是允許(但不是必需的)相等。

如果編譯器將兩個匿名函數表達式視為相等,則第二行將取消訂閱事件中的先前匿名方法。 如果不是,則第二行不會執行任何特殊操作(如果列表中尚不存在代理,則從事件調用列表中取消訂閱不是錯誤)。

是一個關於C#中lambda表達式的精彩視頻。 該視頻已有2年歷史,但它讓用戶能夠快速掌握當時相對較新的功能。 您感興趣的內容將在3:02左右開始。

這是一個錯誤。 它正在向MyEvent事件添加匿名委托,但試圖刪除同一個匿名委托的不同實例。 由於實例可能總是不同,它實際上可能永遠不會刪除原始委托,這幾乎肯定不是你想要的。

它是使用lambda表達式的事件處理程序的實現。 優點是它是a)內聯,即不需要額外的函數聲明,b)它可以繪制在你發現這個聲明的函數中聲明的變量(使用閉包)。

看起來他認為這相當於:

var eh = new EventHandler(delegate(object o, EventArgs e)
    { fCount++; Console.WriteLine(fCount); };

foo.MyEvent += eh;

foo.MyEvent -= eh;

但取消注冊不會按預期工作,因為它無法知道它應該指的是注冊代表。

他用於添加處理程序的語法只是將匿名委托附加到事件的一種較短方式,並且是非常流行的語法,但如果您還必須取消注冊它,我不推薦使用它。

Lambda表達式是聲明函數的語法簡寫。 所以,

(o, e) => { fCount++; Console.WriteLine(fCount); }

表示一個帶有兩個參數並執行兩個語句的函數。

至於代碼片段,取消訂閱' - ='將不起作用,因為它是以下的簡寫:

foo.MyEvent += new EventHandler( (o, e) => { fCount++; Console.WriteLine(fCount); } );
foo.MyEvent -= new EventHandler( (o, e) => { fCount++; Console.WriteLine(fCount); } );

這實際上是資源泄漏。 而是存儲對處理程序的引用,並使用它來執行訂閱和取消訂閱:

var handler = new EventHandler( (o, e) => { fCount++; Console.WriteLine(fCount); } );
foo.MyEvent += handler;
foo.MyEvent -= handler;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM