根據你在這裏的問題和你對Jon的回答的評論我認爲你混淆了多個事情。爲了確保它是明確的:
- 的方法是備份代理對於給定的λ是永遠不變的。
- 的方法是備份該詞彙出現兩次是允許是一樣的「相同」拉姆達的代表,但在實踐中是不在我們的實現是相同的。
- 委託實例爲給定的lambda創建的可能會也可能不總是相同的,這取決於編譯器是如何聰明地緩存它的。
所以,如果你有這樣的:
for(i = 0; i < 10; ++i)
M(()=>{})
然後每M被調用時,你會得到委託的同一個實例因爲編譯器是聰明的,併產生
static void MyAction() {}
static Action DelegateCache = null;
...
for(i = 0; i < 10; ++i)
{
if (C.DelegateCache == null) C.DelegateCache = new Action (C.MyAction)
M(C.DelegateCache);
}
如果您有
for(i = 0; i < 10; ++i)
M(()=>{this.Bar();})
那麼編譯器生成
void MyAction() { this.Bar(); }
...
for(i = 0; i < 10; ++i)
{
M(new Action(this.MyAction));
}
你每次都獲得新的委託,用同樣的方法。
編譯器是允許(但事實上並沒有在這個時候)產生
void MyAction() { this.Bar(); }
Action DelegateCache = null;
...
for(i = 0; i < 10; ++i)
{
if (this.DelegateCache == null) this.DelegateCache = new Action (this.MyAction)
M(this.DelegateCache);
}
在這種情況下,如果可能的話,你會總是得到相同的委託實例,每一個代表將由備份同樣的方法。
如果有
Action a1 =()=>{};
Action a2 =()=>{};
然後,在實踐中,編譯器會生成此作爲
static void MyAction1() {}
static void MyAction2() {}
static Action ActionCache1 = null;
static Action ActionCache2 = null;
...
if (ActionCache1 == null) ActionCache1 = new Action(MyAction1);
Action a1 = ActionCache1;
if (ActionCache2 == null) ActionCache2 = new Action(MyAction2);
Action a2 = ActionCache2;
然而,編譯器是允許以檢測這兩個lambda表達式是相同的並且產生
static void MyAction1() {}
static Action ActionCache1 = null;
...
if (ActionCache1 == null) ActionCache1 = new Action(MyAction1);
Action a1 = ActionCache1;
Action a2 = ActionCache1;
現在清楚了嗎?
「同樣的效果」究竟意味着什麼?調用'GetCurrentMethod'顯然沒有相同的效果... – Mehrdad 2011-06-08 14:54:56
這聽起來對我來說是正確的,儘管如果lambda「捕獲」泛型方法的類型參數,事情也會變得棘手。即使它不使用本地或參數,它仍然可能無法緩存在靜態字段中。 – 2011-06-08 15:00:02
@Eric:[我的一個測試用例](http://stackoverflow.com/questions/4986023/restricting-scope-of-a-class-member-beyond-private/4986143#4986143)使用'public static Local實例(函數作用域)',其中'()=> this'被傳遞給作用域。在這種情況下,它仍然返回相同的代表。 –
2011-06-08 15:09:49