2011-08-24 126 views
3

我不知道是否有簡單的方法來強制匿名函數的參數評估?對於多線程編程,這是重要的匿名函數的力參數評估

。 例如,當我寫

 for(int i=0; i<5; ++i) 
     { 
      Task.Factory.StartNew(() => Console.WriteLine(i)); 
     } 

大多數人會得到「5」五次。事實上代碼剪斷更可能預期輸出中0到5

一個快速的解決方案如下:

 for(int i=0; i<5; ++i) 
     { 
      var local = i; 
      Task.Factory.StartNew(() => Console.WriteLine(local)); 
     } 

我覺得生命是更好,如果下面的方法存在以評估匿名函數和返回的所有參數一個邏輯與原點相同:

Action EvaluateParameters(Action action) 

任何想法?

謝謝。

+0

他們將如何獲得5次,5次? – 2011-08-24 12:10:22

+5

@CodeMonkey:試試吧,它是真的。 Eric Lippert寫的那篇文章:http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx – Jens

+0

@Jens:啊有趣。 – 2011-08-24 12:13:45

回答

0

我不知道如果沒有編譯器或框架支持,這種方法甚至可能(合理)。最後,編譯器會生成代碼來提升變量,而不是在創建代理時的值,這會導致該行爲。

基本上,您將不得不「執行」「EvaluteParameters」中的委託來使其工作。或者也許可以用某種方法來處理表達式。

BTW,這只是一個問題,如果委託創建的循環,但調用(後)外面。

呵呵,ReSharper確實有一個警告(即使它有時是「錯誤的」或過於迂腐)。無論如何,Jon Skeet在他的書(C#深入)中提到,在社區中確實存在一些困惑,並且微軟正在考慮在未來的版本中改變行爲(希望我能夠在某種程度上是正確的從記憶裏)。如果不破壞取決於當前行爲的現有代碼(或者由於它而意外工作),那麼這甚至是不可能的。

+0

謝謝。我也認爲實現它的唯一方法是通過表達式(匿名函數)並正確評估參數。 – scleung