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

问题描述 投票:0回答:2

编辑:这是这个问题的一个更简单的例子(我已经删除了我原来的问题):

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的有趣的链接提供了这种行为的原因,(这不是

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已经强调的那样。注意:这三种方法都是安全的并且给出正确的结果。

.net vb.net linq linq-to-dataset
2个回答
4
投票

Eric Lippert 就此主题撰写了几篇博客文章(代码示例使用 C#,而不是 VB),其中讨论了此类代码可能出现的一些“陷阱”,您可能会觉得有趣:

关闭循环变量被认为是有害的


3
投票

正如消息所说,它“可能会产生”不良影响。在您的情况下,

.ToList()
使其安全,但这对于编译器来说很难验证。

我建议采用复制到本地变量(

Dim exc = excel
)作为标准的“最佳实践”

© www.soinside.com 2019 - 2024. All rights reserved.