2016-09-18 21 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对此是错误的。 –

相关问题