Pourquoi voudriez-vous vérifier Assigned (self) dans les méthodes d'objet?

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

  •  22-07-2019
  •  | 
  •  

Question

Je regarde du code (Delphi 7) dont la vérification suivante se trouve en haut de chaque appel de méthode pour un objet spécifique:

if not Assigned(self) then
  raise Exception.CreateRes(@sAbstractError);

  { Real code for this method}

Je suppose que cela m'empêcherait d'essayer d'appeler une méthode sur un pointeur d'objet nul. Mais j'obtiendrais une exception dès que j'essayerais d'accéder aux données des membres dans ce cas de toute façon, non?

S'agit-il d'un type de norme que je n'ai jamais vu auparavant? L'objet en question provient de TPersistent.

Était-ce utile?

La solution

Vous pouvez appeler une méthode d'instance sur un pointeur null, même si ce n'est pas le genre de chose que vous voulez faire délibérément. Lorsque cela se produit, l’exécution se poursuit sans problème jusqu’à ce qu’elle ait besoin d’accéder aux données de l’instance, puis tout se passe pour le mieux.

Dans ce cas, le fait de rechercher la valeur "nil" vous alertera en haut de la procédure pour vous permettre de faire autre chose, comme consigner une trace de pile. Vous pouvez également placer un point de rupture sur la ligne de relèvement afin de pouvoir plonger et voir ce qui se passe.

C’est quelque chose que je pourrais faire si j’avais un bogue spécifique que j’essayais de localiser là où une référence nulle était utilisée.

Cela me semble être une odeur de code.

Autres conseils

Il est préférable de se plaindre d'un pointeur "Nil" qu'une violation d'accès qui ne dit pas comment cela s'est passé.

Il existe des scénarios de violation d'accès pouvant entraîner l'exécution de code en mémoire où Self est défini sur nil. Certains programmeurs, au lieu de résoudre le vrai problème, tentent de contourner, en utilisant de telles assertions, pour empêcher les corruptions de toutes sortes. Je vérifierais très bien si cette exception se produit au moment de l'exécution, le cas échéant, vous avez un code erroné entre vos mains.

Vous pouvez lire l'article suivant sur le sujet: Quand le moi est à zéro ... vous savez Vous êtes en difficulté .

Une autre possibilité est liée aux événements. Vous pouvez en lire plus ici, avec de nombreux exemples pour de tels tests et les explications correspondantes: Événements de multidiffusion - Partie 2 .

C’est une occasion qui devrait certainement entraîner un blocage (c’est-à-dire une exception de système d’exploitation telle que "lire à partir de l’adresse 0x00000000"). Lancer une exception de langage est simplement redondant (et utiliser EAbstractError de manière abusive ne le rend pas meilleur).

La vérification de paramètres d'entrée valides n'est pas une tâche réalisable dans un langage non sécurisé, car vous ne gagnerez jamais en certitude, et votre traitement des paramètres non valides ne sera donc jamais cohérent. (Pourquoi lancez-vous une exception lorsqu'un pointeur nil est passé, mais pas pour 0x00000001, qui est tout aussi invalide?). Pour une discussion plus technique sur cette question, consultez le blog de Larry Osterman sur pourquoi ne pas rechercher des pointeurs valides .

Il convient de noter une exception: dans Delphi, la méthode Free peut être appelée sur un pointeur nil, ce qui nécessite bien entendu ce type de vérification.

Et puis, il y a toujours la possibilité que le code ne plante pas avec nil Self. Exemple - s'il n'accède pas aux champs de l'objet propriétaire. Dans ce cas, ce test identifiera le problème qui n’aurait autrement pas été détecté.

Pourtant, cela prend la programmation défensive à l'extrême. Je ne fais jamais ça (ok, presque jamais - seulement quand je chasse des wabbits ... mais ... des bugs).

Il semble que l'intention initiale de cette méthode soit qu'elle devienne une méthode abstraite.

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