Сегодня я исследовал логическую ошибку в нашем программном обеспечении и выяснил, что это связано с тем, как переменные потока 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, сохраняет свое значение для следующей итерации. Это специально: http://social.msdn.microsoft.com/Forums/en/vblanguage/thread/c9cb4c22-d40b-49ff-b535-19d47e4db38d, но это также опасная ловушка для программистов.
Однако до сих пор я не знал об этой проблеме / поведении. До сих пор.
В любом случае, большая часть нашей базы кода - это C #, которая не позволяет использовать неинициализированную переменную, поэтому проблем нет.
Но у нас есть некоторый устаревший код, написанный на VB.NET, который мы должны поддерживать.
Я не думаю, что кто-либо из нашей команды разработчиков когда-либо использовал это специально. Если я явно хочу поделиться переменной над итерациями внутри цикла for, я объявляю ее вне области действия.
Так что лучше всего было бы создать предупреждение или даже ошибку в этом конкретном случае.
Но даже с Option Explicit / Option Strict это не генерирует предупреждение / ошибку.
Есть ли способ сделать это ошибкой во время компиляции или, может быть, способ проверить это с помощью FxCop?