La fenêtre de la montre Heisenberg
Cela peut vous mordre si vous faites du 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;
}
}
Maintenant, disons que vous avez du code ailleurs qui utilise ceci :
// blah
// blah
MyObj.DoStuff(); // Line 3
// blah
Maintenant, vous voulez déboguer votre CreateMyObj()
méthode. Vous placez donc un point d'arrêt sur la ligne 3 ci-dessus, avec l'intention d'entrer dans le code. 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 dans CreateMyObj()
lui-même.
Le code atteint votre point d'arrêt à la ligne 3. Vous entrez dans le code. Vous vous attendez à entrer le code conditionnel, car _myObj
est évidemment nulle, non ? Euh... alors... pourquoi il a ignoré la condition et est passé directement à... return _myObj
? ! Vous passez votre souris sur _myObj... et effectivement, il a une valeur ! Comment cela est-il arrivé ? !
La réponse est que votre IDE lui a donné une valeur, parce que 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 à 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, ignorer l'un de vos points d'arrêt il a calculé la valeur de MyObj
pour vous - y compris l'appel à CreateMyObj()
qui définit la valeur de _myObj !
C'est pourquoi je l'appelle la fenêtre d'observation d'Heisenberg - vous ne pouvez pas observer la valeur sans l'affecter... :)
GOTCHA !
Modifier - Je pense que le commentaire de @ChristianHayter mérite d'être inclus dans la réponse principale, car il semble être une solution de contournement efficace pour ce problème. Donc, chaque fois que vous avez une propriété chargée paresseusement...
Décorez votre propriété avec [DebuggerBrowsable(DebuggerBrowsableState.Never)] ou [DebuggerDisplay("<loaded on demand>")]. - Christian Hayter
158 votes
Retourner DateTime.Now.AddDays(1) ;
24 votes
À ma connaissance, les types de valeurs intégrés sont tous immuables, du moins dans la mesure où toute méthode incluse dans le type renvoie un nouvel élément plutôt que de modifier l'élément existant. Du moins, je n'en vois pas un seul qui ne fasse pas cela : tout est beau et cohérent.
1 votes
Wiki communautaire, tellement de spam dans SO maintenant. Lorsque les questions sont subjectives (pas de réponse définitive), il devrait s'agir d'un wiki communautaire.
6 votes
Type de valeur mutable : System.Collections.Generics.List.Enumerator :( (Et oui, vous pouvez voir qu'il se comporte bizarrement si vous essayez suffisamment).
0 votes
Lol, je savais qu'il y aurait des exceptions. L'énumérateur semble un peu... spécial de toute façon. Laissez-moi affiner cela aux types directement sous l'espace de noms System, bien que même là vous pourriez trouver quelque chose.
14 votes
L'intellisense vous donne toutes les informations dont vous avez besoin. Il est dit qu'il retourne un objet DateTime. S'il modifiait simplement celui que vous avez transmis, ce serait une méthode void.
22 votes
Pas nécessairement : StringBuilder.Append(...) renvoie "this" par exemple. C'est assez courant dans les interfaces fluentes.
4 votes
C'est pourquoi j'aime la convention '!' en Lisp, AddDays (renvoie une nouvelle valeur) et AddDays ! (modifie une valeur existante) sont facilement et instantanément distinguables.
4 votes
Ne détestez-vous pas tous ces messages de type "what is your biggest/funniest/etc <whatever>" sur SO ?
1 votes
Les structs dans
System.Drawing
(versions Point, Size, Rectangle et float) sont toutes mutables.Color
ne l'est pas, cependant.2 votes
Devrait être nommé
dt.NextDays(1);
les programmeurs n'auront pas la moindre idée qu'il modifie sa propre valeur. De la même manière que les constructions de structures de données (par ex.node->next
,node.next
) ne modifie pas la valeur du noeud. Et c'est trop tard maintenant, ils pourraient donner àdt.AddDays(1)
la sémantique qu'il ajoute des jours dans sa propre valeur.1 votes
Je suis d'accord pour dire que l'exemple donné est une question de dénomination. Le nom de la méthode implique qu'elle s'ajoute à la date. Quelque chose comme
dt.PlusDays(1)
serait plus clair. Un autre problème avec cette méthode est qu'elle n'accepte qu'un fichierdouble
donc le résultat n'est pas exact.0 votes
Je gagnerais cette question si une personne stupide n'avait pas fermé ce sujet. Je connais l'insecte le plus maléfique du monde. S'il vous plaît voir codeproject.com/Feature/
1 votes
@bluefeet, comme les utilisateurs ont fourni >= 62 réponses (y compris Jon Skeet), beaucoup d'entre elles avec des centaines de upvotes, apparemment alors les utilisateurs veulent même ces types de questions. Soit cela constitue un type de question approprié, soit il est temps d'apporter un amendement constitutionnel à toutes les règles restrictives de la SO.
0 votes
5.add(2) ; 5 devrait toujours être 5.