La fenêtre de surveillance de Heisenberg
Cela peut vous mordre gravement si vous effectuez des tâches de chargement à la demande, comme ceci:
private MyClass _myObj;
public MyClass MyObj {
get {
if (_myObj == null)
_myObj = CreateMyObj(); // some other code to create my object
return _myObj;
}
}
Supposons maintenant que vous ayez du code ailleurs en utilisant ceci:
// blah
// blah
MyObj.DoStuff(); // Line 3
// blah
Vous voulez maintenant déboguer votre CreateMyObj()
méthode. Vous avez donc mis un point d'arrêt sur la ligne 3 ci-dessus, avec l'intention d'entrer dans le code. Juste pour faire bonne mesure, vous mettez également un point d'arrêt sur la ligne ci-dessus qui dit _myObj = CreateMyObj();
, et même un point d'arrêt à l'intérieur de CreateMyObj()
lui-même.
Le code atteint votre point d'arrêt sur la ligne 3. Vous entrez dans le code. Vous vous attendez à entrer le code conditionnel, car _myObj
est évidemment nul, non? Euh ... alors ... pourquoi at-il sauté la condition et est allé directement à return _myObj
?! Vous passez votre souris sur _myObj ... et en effet, cela a une valeur! Comment est-ce arrivé?!
La réponse est que votre IDE lui a fait obtenir une valeur, car vous avez une fenêtre de "surveillance" ouverte - en particulier la fenêtre de surveillance "Autos", qui affiche les valeurs de toutes les variables / propriétés pertinentes pour la ligne d'exécution actuelle ou précédente. Lorsque vous avez atteint votre point d'arrêt sur la ligne 3, la fenêtre de surveillance a décidé que vous seriez intéressé de connaître la valeur de MyObj
- donc dans les coulisses, en ignorant l'un de vos points d'arrêt , il est allé et a calculé la valeur de MyObj
pour vous - y compris l'appel à CreateMyObj()
ce définit la valeur de _myObj!
C'est pourquoi j'appelle cela la fenêtre de surveillance Heisenberg - vous ne pouvez pas observer la valeur sans l'affecter ... :)
JE T'AI EU!
Edit - Je pense que le commentaire de @ ChristianHayter mérite d'être inclus dans la réponse principale, car il ressemble à une solution de contournement efficace pour ce problème. Donc, chaque fois que vous avez une propriété paresseuse ...
Décorez votre propriété avec [DebuggerBrowsable (DebuggerBrowsableState.Never)] ou [DebuggerDisplay ("<chargé à la demande>")]. - Christian Hayter