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.

<!--4 - VB.NET, une variable qui est déclarée à l'intérieur d'un for loop conserve sa valeur pour la prochaine itaration. C'est à dessein: http://social.msdn.microsoft.com/Forums/en/vblanguage/thread/c9cb4c22-d40b-49ff-b535-19d47e4db38d mais c'est aussi un piège dangereux pour les programmeurs.

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?

10
demandé sur Jürgen Steinblock 2012-03-27 13:11:50

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.

2
répondu J... 2012-03-27 10:23:58

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.

0
répondu Chris Dunaway 2012-03-27 14:26:40

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.

0
répondu Mark Hurd 2012-07-31 16:06:32