Variable déclarée à l'intérieur d'une boucle for. Comment faire pour que ce soit une erreur de compilation?
Aujourd'hui j'ai enquêté sur un bug logique dans notre logiciel et j'ai compris que c'est lié à la façon dont VB.NET variables de thread à l'intérieur d'une boucle.
disons que j'ai le code suivant:
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
produit la sortie suivante
1 is Odd
2 is Even
3 is Even
4 is Even
5 is Even
Le problème est que isEven
est déclaré mais non assigné.
Dans ce cas précis, il serait correct d'écrire dim isEven as Boolean = false
mais je n'ai pas fait cela.
cependant, jusqu'à maintenant, je n'étais pas au courant de ce problème/comportement. Jusqu'à aujourd'hui. La plupart de notre base de code est C# de toute façon, ce qui ne permet pas l'utilisation d'une variable non initialisée, donc il n'y a pas de problème.
mais nous avons du code d'héritage c'est écrit en VB.NET que nous devons soutenir.
je ne pense pas que quelqu'un de notre équipe de dev n'a jamais utilisé ce but. Si je veux explicitement partager une variable sur des itérations à l'intérieur d'une boucle for, je la déclare en dehors de la portée.
Donc la meilleure chose serait de générer un avertissement ou même une erreur dans ce cas précis. Mais même avec L'Option explicite / Option stricte, cela ne génère pas d'avertissement / d'erreur.
Est-il possible de faire cette erreur de compilation ou peut-être un moyen de vérifier avec FxCop?
3 réponses
Je ne pense pas que quelqu'un de notre équipe de développement ait jamais utilisé ceci avec but. Si je veux explicitement partager une variable sur des itérations à l'intérieur d'une boucle for, je la déclare en dehors de la portée.
je suppose que le point entier de déclarer une variable à l'intérieur de la boucle est de restreindre explicitement son champ d'application à ce bloc, cependant. Pour faire cela une erreur de temps de compilation supprimerait la portée de niveau bloc de la langue. Bien qu'il y ait certainement des cas où le niveau de la méthode il ne fait aucun doute que l'on peut également faire valoir l'importance du champ d'application au niveau du bloc. Je ne pense pas que vous puissiez facilement l'extraire du langage sans introduire une nouvelle méthode syntaxique pour l'utiliser. À ce stade, vous entrez dans le domaine de la refonte VB.NET - Je ne suis pas sûr qu'il y ait un moyen facile de faire ça.
Regardez le code ci-dessous. Si ne pas permettre une déclaration sans initialisation est une erreur de compilateur, alors ce code ne produirait pas la sortie correcte (un total courant de nombres pairs). Si vous me forcer à initialiser la valeur de 'total', la méthode ne peut être correcte.
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
au lieu d'ajouter une erreur, il suffit de corriger la logique dans le code. Je ne vois pas cela comme particulièrement dangereux écueil. La plupart des programmeurs seraient en mesure de reconnaître ce problème, et unité les tests devraient également aider à déceler ces types de problèmes.
si vous pensez que cela peut être un problème avec votre base de codes ou vos programmeurs, dans votre style de codage spécifiez que toutes les variables non initialisées sont déclarées au début de la routine. Il s'agissait d'une ligne directrice de style courante (surtout pour la VB) jusqu'à la prévalence de l'inférence de type.
bien sûr, il n'évite pas le problème, il suffit en fait de plus en plus évidents.