2012-04-12 45 views
4

ReSharper的提供我使這個局部變量,並寫入「訪問修改關閉」爲什麼要局部變量?

if (filter != null) 
{ 
    if (filter.CityId != 0) 
    { 
     ads = ads.Where(x => x.Ad.CityId == filter.CityId); 
    } 
    if (filter.BusinesCategoryId != 0) 
    { 
     ads = ads.Where(x => x.BusinessCategoryId == filter.BusinesCategoryId); 
    } 
} 

爲什麼局部變量過濾器?

+2

哪個局部變量'ads'? – Tigran 2012-04-12 05:32:04

回答

6

因爲您的查詢(Where(...))未被執行。我假設過濾器是從循環中獲得的?

直到它們被使用時才執行Linq查詢。所以如果你通過一堆過濾器循環,然後開始執行它們,那麼過濾器的值在查詢中會出錯。

一個類似的問題:Access to Modified Closure 另外:http://devnet.jetbrains.net/thread/273042

需要看到更多的代碼,以100%的把握。

+0

有一個週期是危險的嗎?我不循環。 – Mediator 2012-04-12 06:38:57

+2

可以不用循環修改閉包。循環是無意修改的閉包變量的最常見原因,但它不是唯一的原因。 – phoog 2012-04-12 06:43:10

3

從我的理解來看,如果從委託(閉包)訪問變量,Resharper會拋出一個錯誤,然後在執行委託之前修改該變量。如果你在一個委託/ lambda中訪問一個for循環變量,並在循環之外執行它,這大多會發生。如果你的代碼是這樣的:

foreach (filter in filters) 
{ 
     if (filter != null) { 
      if (filter.CityId != 0)  { 
       ads = ads.Where(x => x.Ad.CityId == filter.CityId); 
      } 
      if (filter.BusinesCategoryId != 0)  { 
       ads = ads.Where(x => x.BusinessCategoryId == filter.BusinesCategoryId); 
      } 
     } 
} 
return ads.ToList() 

然後它不會像你期望的那樣。但是如果你在循環範圍內執行lambda表達式,那麼你就沒有問題了。

我不會解釋爲什麼它的行爲,那是因爲很多人已經解釋得很好:

更新: 要回答「爲什麼要局部變量?」是因爲上述問題的解決方法是使用局部變量(即,在循環內)並在您的lambda中使用該變量。這樣你就可以關閉每個lambda實例的變量的不同實例。

相關問題