警告:"在lambda表达式中使用迭代变量可能会产生意外结果"

时间:2011-08-29 10:57:03

标签: .net vb.net linq compiler-construction linq-to-dataset

修改:这是一个更简单的问题示例(我deleted我原来的问题):

Dim numbers1 As New List(Of Int32)({1, 2, 3})
Dim numbers2 As New List(Of Int32)({3, 4, 5})
For Each n1 In numbers1
    ' no warning '
    Dim contains = numbers2.Contains(n1)
Next
For Each n1 In numbers1
    ' warning on n1'
    Dim contains = (From num In numbers2 Where num = n1).Any
Next

所以我仍然不明白为什么编译器认为我可能在第二次迭代中得到意想不到的结果,而我对第一次安全是安全的。我不认为@ ee-m的interesting link提供了这种行为的原因,(这不是for-each问题,For n1 As Int32 = 1 To 3也会导致编译器警告)。

我真的不相信以下应该是“最佳实践”:

For Each n1 In numbers1
    Dim number1 = n1
    ' no warning'
    Dim contains = (From num In numbers2 Where num = number1).Any
Next

局部变量number1是多余的,并且使代码的可读性降低,正如@ Meta-Knight已经强调的那样。注意:这三种方式都是安全的,并给出了正确的结果。

2 个答案:

答案 0 :(得分:4)

Eric Lippert撰写了几篇关于这个主题的博客文章(代码示例在C#中,而不是VB),这些文章介绍了这些代码可能会产生的一些“问题”:

Closing over the loop variable considered harmful

答案 1 :(得分:3)

正如消息所说,它“可能有”不受欢迎的影响。在您的情况下,.ToList()使其安全,但编译器很难验证。

我建议采用复制到本地var(Dim exc = excel)作为标准“最佳实践”