2013-03-03 94 views
0

我有以下類。從KeyValuePair獲取重要參考

public class myType 
{ 
    public event Action myAction; 
} 

以及包含該類的一些實例的字典。

var myDictionary = new Dictionary<myType, string>(); 

在我主我有簽名 無效的someMethod的方法(的myType,字典)

用下面的循環添加我的對象的行爲:

foreach(var pair in myDictionary) 
    pair.Key.myAction +=() => SomeMethod(pair.Key, myDictionary); 

運行該循環之後,當我的一個對象的動作被調用時,效果就好像循環已經使用了字典中所有lambda表達式的最後一個pair.Key。

在另一方面與環中的小變化:

foreach(var pair in myDictionary) 
{ 
    myType temp = pair.Key; 
    pair.Key.myAction +=() => SomeMethod(temp, myDictionary); 
} 

運行該循環後,所有對象的動作正常工作。

我有點茫然,爲什麼這樣的改變會產生這樣的效果。 keyvaluepair可能是一個結構體,通過鍵本身就是一個引用類型(我的類的一個實例)。任何想法爲什麼這樣表現?

在此先感謝您的任何建議。

回答

1

運行該循環後,當我的對象之一的作用是 調用,其效果是如果循環使用過的最後一個pair.Key在 字典中所有的lambda表達式。

是的,這正是發生了什麼事情。您有一個由所有事件處理程序使用的變量pair。循環後,變量包含循環中最後一項的鍵。

通過在作用域中創建局部變量並在lambda表達式中使用它,實際上是爲每個事件處理程序創建一個閉包。本地變量不是作爲常規本地變量存儲在堆棧中的,而是在閉包中,並且由於每個事件處理程序都有自己的閉包,因此每個事件處理程序都會得到一個局部變量版本。

(沒有與第一代碼也封閉,但是這僅僅是變量生存的電流範圍,事件處理程序共享相同的關閉。)

+0

感謝您在清除了。 – 2013-03-04 10:01:13