首页 文章

变量在for循环中声明 . 如何使这成为编译时错误?

提问于
浏览
10

今天我调查了我们软件中的一个逻辑错误,并发现这与循环中VB.NET线程变量的方式有关 .

假设我有以下代码:

Dim numbers As New List(Of Integer) From {1, 2, 3, 4, 5}
    For Each number As Integer In numbers

        Dim isEven As Boolean

        If number Mod 2 = 0 Then
            isEven = True
        End If

        If isEven Then
            Console.WriteLine(number.ToString() & " is Even")
        Else
            Console.WriteLine(number.ToString() & " is Odd")
        End If

    Next

产生以下输出

1 is Odd
2 is Even
3 is Even
4 is Even
5 is Even

问题是 isEven 已声明但未分配 . 在这个特定的情况下,写 dim isEven as Boolean = false 是正确的,但我还没有这样做 .

在VB.NET中,在for循环中声明的变量保留其下一个itaration的值 . 这是设计:http://social.msdn.microsoft.com/Forums/en/vblanguage/thread/c9cb4c22-d40b-49ff-b535-19d47e4db38d但这对程序员来说也是一个危险的陷阱 .

但是,直到现在,我还没有意识到这个问题/行为 . 到现在 . 我们的代码库大部分都是C#,它不允许使用未初始化的变量,所以没有问题 .

但是我们有一些用VB.NET编写的遗留代码,我们必须支持 .

我不认为我们的开发团队中的任何人都曾用过这个目的 . 如果我明确想要在for循环内的迭代中共享变量,我将其声明在范围之外 .

因此,最好的办法是在这种特定情况下产生警告甚至错误 . 但即使使用Option Explicit / Option Strict,也不会产生警告/错误 .

有没有办法使这个编译时错误或者可能用FxCop检查这个?

3 回答

  • 0

    我认为开发团队的任何人都没有用过这个目的 . 如果我明确想要在for循环内的迭代中共享变量,我将其声明在范围之外 .

    我认为在循环中声明变量的重点是明确地将其范围限制为该块 . 要使这成为编译时错误,将从语言中删除块级范围 . 虽然确实存在方法级范围合理的情况,但毫无疑问也会出现块级范围重要性的情况 . 我不认为你可以轻易地从语言中删除它,而不引入一些新的句法方法来使用它 . 此时您正在进入重新设计VB.NET的领域 - 我不确定是否有一种简单的方法可以做到这一点 .

  • 2

    看下面的代码 . 如果在没有初始化的情况下不允许声明是编译器错误,那么此代码将不会产生正确的输出(偶数运行总计) . 如果你强迫我初始化'total'的值,那么该方法永远不会是正确的 .

    Dim numbers As New List(Of Integer) From {1, 2, 3, 4, 5, 6, 8, 9, 10}
    For Each number As Integer In numbers
    
        Dim total As Integer
    
        Dim isEven As Boolean = (number Mod 2 = 0)
    
        If isEven Then
            total += number
            Console.WriteLine("Running Total: {0}", total)
        End If
    Next
    

    而不是添加错误,只需修复代码中的逻辑 . 我不认为这是一个特别危险的陷阱 . 大多数程序员都能够识别这个问题,单元测试也应该有助于发现这些类型的问题 .

  • 0

    如果您认为这可能是您的代码库或程序员的问题,那么在您的编码风格中指定在例程开始时声明所有未初始化的变量 . 这是一种常见的样式指南(特别是对于VB),直到类型推断的普遍存在 .

    当然它不能避免这个问题,只是让它更明显 .

相关问题