2016-09-18 41 views
3

如果這是一個重複的問題,我很抱歉。我在這裏看到很多關於「修改關閉」的問題,但沒有一個能夠解決我所看到的問題。爲什麼Resharper將此標記爲「訪問修改後的閉包」?

Resharper 2016.2將lambda表達式中「b」和「i1」的使用標記爲「訪問修改後的閉包」。我不認爲它應該。我從來沒有在程序的其他地方使用b或i或i1。兩者都是在循環中聲明的 - 事實上,i1是由Resharper創建的,用於解決修改後的關閉問題。我可以嘗試用i1來解決它,它只會創建一個「int i2 = i1」,並仍然給我i2的警告!這當然不對。我在這裏錯過了什麼?

for (int i = 0; i < 10; ++i) { 
    Button b = new Button(); 
    int i1 = i; 
    Invoker.SyncInvoke(b,() => { b.Text = "number " + i1; }); 
} 

編輯: 這必須是一個錯誤。在一個特定的源文件中的一個點(以線424,要準確)是這三條線:

 var collapsed = daSheet; 
     int numrows = collapsed.GetLastNonEmptyRow(NonEmptyItemFlag.Data); 
     int numcols = collapsed.GetLastNonEmptyColumn(NonEmptyItemFlag.Data); 

如果我粘貼上面的代碼(在上面循環)的行之前,我沒有得到任何警告。如果我在這些行後貼上它,我會收到關於「b」和「i1」的警告。如果我將它粘貼在第二行和第三行之間,我會收到有關「i1」的警告,但不會顯示b。這是沒有意義的。

+1

許多在Resharper上工作的聰明人沒有冒犯,但是 - 他們的一些分析儀的誤報率非常糟糕。我不認爲你錯過了什麼;我認爲這不是一個很好的分析器。 –

+0

使用Invoker.SyncInvoke是多餘的;正在創建一個按鈕並正在分配文本,但該按鈕尚未添加到控件集合中。 –

+0

如果這段代碼是一個簡單的例子,它可能被簡化得太多了,但很難說。 – jdphenix

回答

0

「爲他們的一些分析儀的誤報率是非常可怕」 - your're右^^

其實ReSharper的是不是錯了。

想象一下,而不是調用...你會用這樣的Task.Startnew(...) 我假設(只讀源),執行後,你沒有10個不同的按鈕,你有隻有一個,這個有「數字9」的文字。

因爲編譯器會將lambda表達式中的按鈕和i1參數放在一起,所以通常需要使用dotpeek 查看已反編譯的源代碼。

+0

您誤會了。你肯定會有10個按鈕,因爲你稱爲「新的按鈕()」10次。如果你在lambda中使用了循環計數器「i」,所有的按鈕將會(或者可能會根據代碼的實際執行時間)說出「按鈕9」。創建一個本地作用域變量(被lambda阻塞)使其工作正確。 Resharper對此是錯誤的。 –

相關問題