259 votes

Quand dois-je utiliser Debug.Assert() ?

Je suis ingénieur logiciel professionnel depuis environ un an maintenant, après avoir obtenu un diplôme en informatique. Je connaissais les assertions depuis un certain temps en C++ et C, mais je ne savais pas du tout qu'elles existaient en C# et .NET jusqu'à récemment.

Notre code de production ne contient aucune assertion et ma question est la suivante...

Devrais-je commencer à utiliser les alertes dans notre code de production ? Et si oui, quand son utilisation est-elle la plus appropriée ? Serait-il plus judicieux de faire

Debug.Assert(val != null);

ou

if ( val == null )
    throw new exception();

4 votes

La dichotomie que vous avez mise en place est l'indice. Il ne s'agit pas de l'un ou l'autre pour les exceptions et les assertions, mais de l'un et l'autre pour le code défensif. Ce que vous cherchez à comprendre, c'est quand faire l'un ou l'autre.

7 votes

J'ai lu une fois que quelqu'un suggérait qu'une exception ou une autre méthode de plantage est appropriée pour les conditions où "Il n'y a aucun moyen de se remettre raisonnablement de ceci", et qu'en plus un assert est approprié pour les conditions où "Ceci ne devrait jamais arriver, jamais". Mais quelles circonstances réalistes satisfont ces dernières conditions sans satisfaire également les premières ? Venant d'un environnement Python où les assertions restent actives en production, je n'ai jamais compris l'approche Java/C# consistant à désactiver une partie de la validation en production. Le seul cas que je vois vraiment est celui où la validation est coûteuse.

0 votes

272voto

Rory MacLeod Points 4574

Sur Débogage des applications Microsoft .NET 2.0 John Robbins a une grande section sur les assertions. Ses principaux points sont :

  1. Affirmez librement. On ne peut jamais avoir trop d'affirmations.
  2. Les assertions ne remplacent pas les exceptions. Les exceptions couvrent les choses que votre code exige ; les assertions couvrent les choses qu'il suppose.
  3. Une assertion bien rédigée peut vous dire non seulement ce qui s'est passé et où (comme une exception), mais aussi pourquoi.
  4. Un message d'exception peut souvent être énigmatique, vous obligeant à travailler à rebours dans le code pour recréer le contexte qui a causé l'erreur. Une assertion peut préserver l'état du programme au moment où l'erreur s'est produite.
  5. Les assertions font office de documentation, indiquant aux autres développeurs les hypothèses implicites dont dépend votre code.
  6. La boîte de dialogue qui apparaît lorsqu'une assertion échoue vous permet d'attacher un débogueur au processus, de sorte que vous pouvez fouiller dans la pile comme si vous aviez placé un point d'arrêt à cet endroit.

PS : Si vous avez aimé Code Complete, je vous recommande de le suivre avec ce livre. Je l'ai acheté pour apprendre à utiliser WinDBG et les fichiers de vidage, mais la première moitié est remplie de conseils pour éviter les bogues en premier lieu.

4 votes

+1 pour ce résumé concis et utile. Très directement applicable. La principale chose qui manque pour moi, cependant, est de savoir quand utiliser Trace.Assert vs Trace.Assert. C'est-à-dire quelque chose sur le moment où vous les voulez ou ne les voulez pas dans votre code de production.

3 votes

JonCoombs, "Trace.Assert vs. Trace.Assert" est-il une faute de frappe ?

3 votes

@thelem Peut-être que Jon voulait dire Debug.Assert vs. Trace.Assert . Ce dernier est exécuté dans une version Release ainsi que dans une version Debug.

101voto

Mark Cidade Points 53945

Mettez Debug.Assert() partout dans le code où vous voulez avoir des contrôles de sanité pour assurer les invariants. Lorsque vous compilez une version Release (c'est-à-dire, sans DEBUG constante du compilateur), les appels à Debug.Assert() seront supprimés afin de ne pas affecter les performances.

Vous devez toujours lever des exceptions avant d'appeler Debug.Assert() . L'asserteur s'assure simplement que tout se passe comme prévu pendant que vous êtes encore en train de vous développer.

41 votes

Pourriez-vous préciser pourquoi mettre une assertion si vous lâchez une exception avant de l'appeler ? Ou ai-je mal compris votre réponse ?

2 votes

@romkyns Vous devez quand même les inclure car si vous ne le faites pas, lorsque vous construisez votre projet en Communiqué de presse toutes les validations et vérifications d'erreurs seront supprimées.

33 votes

@Oscar Je pensais que c'était le but de l'utilisation des assertions en premier lieu... OK, donc vous placez les exceptions avant elles - alors pourquoi placer les assertions après ?

55voto

jmfsg Points 18246

De Code complet

8 Programmation défensive

8.2 Assertions

Une assertion est un code utilisé pendant le développement - généralement une routine ou une macro - qui permet à un programme de se vérifier pendant son exécution. ou une macro - qui permet à un programme de se vérifier pendant son exécution. Lorsqu'une assertion est vraie, cela signifie que tout fonctionne comme prévu. Si elle est fausse, cela signifie qu'elle a détecté une erreur inattendue dans le code. code. Par exemple, si le système suppose qu'un fichier d'informations sur le client client ne contiendra jamais plus de 50 000 enregistrements, le programme pourrait le programme peut contenir une assertion selon laquelle le nombre d'enregistrements est ou égal à 50 000. Tant que le nombre d'enregistrements est inférieur ou égal à 50 000, l'assertion est maintenue. 50 000, l'assertion sera silencieuse. Si elle rencontre plus de 50 000 enregistrements, par contre, elle "affirme" bruyamment qu'il y a une erreur dans le erreur dans le programme.

Les assertions sont particulièrement utiles dans les programmes complexes et de grande taille et dans les programmes de haute fiabilité. Elles permettent aux programmeurs d'éliminer plus rapidement d'éliminer plus rapidement les hypothèses d'interface inadéquates, les erreurs qui se glissent dans code est modifié, etc.

Une assertion prend généralement deux arguments : une expression booléenne qui booléenne qui décrit l'hypothèse qui est supposée être vraie et un message à message à afficher si elle ne l'est pas.

( )

Normalement, vous ne voulez pas que les utilisateurs voient les messages d'assertion dans le code de production. code de production ; les assertions sont principalement utilisées pendant le développement et la maintenance. Les assertions sont normalement compilées dans le code au moment du développement et retirées du code pour la production. code au moment du développement et compilées hors du code pour la production. Pendant le développement de développement, les assertions permettent d'éliminer les hypothèses contradictoires, les conditions inattendues, les mauvaises valeurs transmises aux routines, etc. Pendant la production, elles sont compilées en dehors du code afin que les afin que les assertions ne dégradent pas les performances du système.

10 votes

Alors, que se passe-t-il si un fichier d'informations sur les clients rencontré en production contient plus de 50 000 enregistrements ? Si l'assertion est compilée hors du code de production et que cette situation n'est pas gérée autrement, n'est-ce pas un problème ?

2 votes

@DavidRR Oui, en effet. Mais dès que la production signale un problème et qu'un développeur (qui ne connaît peut-être pas bien ce code) débogue le problème, l'assertion échouera et le développeur saura immédiatement que le système n'est pas utilisé comme prévu.

1 votes

Le lien dans la réponse est mort - "Ce site ne peut être joint | cc2e.com a mis trop de temps à répondre."

48voto

Justin R. Points 10122

Utilisez des assertions pour vérifier les hypothèses du développeur et des exceptions pour vérifier les hypothèses de l'environnement.

32voto

Mark Ingram Points 24995

Si j'étais vous, je le ferais :

Debug.Assert(val != null);
if ( val == null )
    throw new exception();

Ou pour éviter un contrôle répété des conditions

if ( val == null )
{
    Debug.Assert(false,"breakpoint if val== null");
    throw new exception();
}

6 votes

En quoi cela résout-il le problème ? Avec cela, le debug.assert devient inutile.

46 votes

Non, il s'introduit dans le code juste avant que l'exception ne soit levée. Si vous avez un try / catch ailleurs dans votre code, vous ne remarquerez peut-être même pas l'exception !

2 votes

+1 J'ai eu beaucoup de problèmes où les gens essayaient simplement d'attraper les exceptions sans rien faire, donc le suivi des bogues était un problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X