Détection automatique du compilateur de l'ajout de la même instance d'objet à un conteneur dans une boucle

StackOverflow https://stackoverflow.com/questions/1465486

Question

C'est une erreur stupide:

List<Foo> fooList = new List<Foo>();
Foo f = new Foo();
while (something.Read()) {
    f.Fill(something.GetRecord());
    fooList.Add(f);
}

Bien sûr, je devrais instancier un nouveau foo à l'intérieur de la boucle.

Un compilateur peut-il détecter ce type d'erreur au moment de la compilation?

Pour les yeux naïfs, il semble qu'il devrait être en mesure de détecter ce comportement (remplir une liste avec des instances du même objet dans une boucle). Il devrait ensuite émettre un avertissement comme "Vous remplissez un conteneur avec la même instance plus d'une fois.".

Alors, à quel point suis-je naïf? Connaissez-vous une langue où quelque chose comme ça existe?

Était-ce utile?

La solution

Oui, c'est possible.

Cependant, je ne pense pas qu'un outil ou un compilateur en avertirait eux-mêmes, vous devez donc utiliser un outil qui peut être étendu avec vos propres analyses. Pour Java, Findbugs est un tel outil. Pour c, c ++, etc., GCC 4.5 permettra les plugins pour que les gens écrivent leurs propres extensions, et bruit De LLVM est également conçu pour cela. Il y a aussi Déshydrate De Mozilla, encore une fois pour C ++. Pour les langues MS, il y a le Framework Phoenix.

La question est donc de savoir comment rédigez-vous cette analyse? C'est un peu plus délicat et dépend de l'outil. Mais fondamentalement:

  • Vous pouvez détecter les boucles assez facilement (recherchez des "composants fortement connectés"),
  • L'analyse d'alias peut vous dire si une variable ou un paramètre particulier fait référence à un seul objet, ou à de nombreux objets (recherchez peut-être des "objets abstraits", peut-être)
  • Vous pouvez trouver le bon conteneur à l'aide du type statique d'un objet ou d'une variable.

Afin que vous puissiez facilement détecter un appel à List<>.append(x) Dans une boucle, où X peut se référer à un seul objet.

Autres conseils

Et si vous souhaitez remplir une liste <> avec plusieurs instances d'un objet? Auriez-vous besoin de décorer votre code avec #pragma Alors le compilateur vous laisse seul?

Comment déclareriez-vous même une classe pour avoir ce genre de restrictions? Liste <> n'est vraiment rien de plus qu'une classe C #, vous pouvez décompiler mscorlib.dll et voir son implémentation complète. Donc, pour avoir ce genre de connaissances, il devrait être codé en dur quelque part. Les attributs? Ce serait incroyablement restreint. Méthodes spéciales pour valider votre code? Ajouterait des frais généraux à vos objets.

Ce genre de choses n'est jamais (et je ne veux jamais dire) utilisée pour une raison: le nombre extrêmement petit de cas où cela aiderait plutôt que de gêner ne s'approche nulle part pour l'emporter sur le coût très réel dont il faudrait les deux difficultés de mise en œuvre (de la Framework lui-même et de votre code) et des performances (à partir d'objets surélevés qui doivent être déplacés dans la mémoire car le GC fait son truc).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top