Code "Débogage uniquement" qui ne doit s'exécuter que lorsqu'il est "activé"


93

Je voudrais ajouter du code C # "débogage uniquement" qui ne fonctionne que si la personne qui déboge le demande. En C ++, j'avais l'habitude de faire quelque chose de similaire à ce qui suit:

void foo()
{   
  // ...
  #ifdef DEBUG
  static bool s_bDoDebugOnlyCode = false;
  if (s_bDoDebugOnlyCode)
  {
      // Debug only code here gets executed when the person debugging 
      // manually sets the bool above to true.  It then stays for the rest
      // of the session until they set it to false.
  }
  #endif
 // ...
}

Je ne peux pas faire exactement la même chose en C # car il n'y a pas de statique locale.

Question : Quelle est la meilleure façon d'accomplir cela en C #?

  1. Dois-je utiliser un champ statique de classe privée avec des directives de préprocesseur C # ( #if/#endif DEBUG)?
  2. Dois-je utiliser l'attribut Conditionnel (pour contenir le code), puis un champ statique de classe privée ( non entouré de directives de préprocesseur C # #if/#endif DEBUG?).
  3. Autre chose?

Réponses:


145

Une variable d'instance serait probablement le moyen de faire ce que vous voulez. Vous pouvez le rendre statique pour conserver la même valeur pendant la durée de vie du programme (ou du thread en fonction de votre modèle de mémoire statique), ou en faire une variable d'instance ordinaire pour la contrôler pendant la durée de vie d'une instance d'objet. Si cette instance est un singleton, ils se comporteront de la même manière.

#if DEBUG
private /*static*/ bool s_bDoDebugOnlyCode = false;
#endif

void foo()
{   
  // ...
#if DEBUG
  if (s_bDoDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }
#endif
 // ...
}

Juste pour être complet, les pragmas (directives de préprocesseur) sont considérés comme un peu un kludge à utiliser pour contrôler le flux du programme. .NET a une réponse intégrée pour la moitié de ce problème, en utilisant l'attribut "Conditionnel".

private /*static*/ bool doDebugOnlyCode = false; 
[Conditional("DEBUG")]
void foo()
{   
  // ...    
  if (doDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }    
  // ...
}

Pas de pragmas, beaucoup plus propre. L'inconvénient est que le conditionnel ne peut être appliqué qu'aux méthodes, vous devrez donc gérer une variable booléenne qui ne fait rien dans une version de version. Comme la variable existe uniquement pour être basculée à partir de l'hôte d'exécution VS, et dans une version de construction, sa valeur n'a pas d'importance, c'est assez inoffensif.


2
Enfin - quelqu'un qui a lu toute la question. Merci, d'accord - cela semblait être une solution longue (devoir avoir les deux sections de préprocesseur), mais c'est peut-être le meilleur C # que je puisse faire pour ce que je veux.
Matt Smith

6
meh. Je n'appellerais pas cela long simplement parce que vous ajoutez deux autres lignes de directive de préprocesseur.
KeithS

4
Merci beaucoup Patrick, d'avoir voté contre une réponse acceptée par un enfant de 3 ans en faveur d'une réponse qui ne résout pas tout le problème. L'attribut conditionnel empêche uniquement la méthode de s'exécuter dans des modes non débogués. L'OP voulait non seulement cela, mais aussi pouvoir "activer" le code à l'aide du débogueur. Et l'étiquette de gokkor telle qu'elle est utilisée ne se compilera pas.
KeithS

2
Notez que le préprocesseur vous indique si le programme est en cours de compilation en mode débogage, mais pas si le débogueur est en cours d'exécution.
Shane

65

Ce que vous cherchez c'est

[ConditionalAttribute("DEBUG")]

attribut.

Si vous écrivez par exemple une méthode comme:

[ConditionalAttribute("DEBUG")]
public static void MyLovelyDebugInfoMethod(string message)
{
    Console.WriteLine("This message was brought to you by your debugger : ");
    Console.WriteLine(message);
}

tout appel que vous faites à cette méthode dans votre propre code ne sera exécuté qu'en mode débogage. Si vous construisez votre projet en mode version, même l'appel à la méthode "MyLovelyDebugInfoMethod" sera ignoré et vidé de votre binaire.

Oh et encore une chose si vous essayez de déterminer si votre code est en cours de débogage au moment de l'exécution, il est également possible de vérifier si le processus actuel est accroché par un JIT. Mais c'est tous ensemble un autre cas. Postez un commentaire si c'est ce que vous essayez de faire.


3
Lorsque vous utilisez Attribute, vous n'avez pas besoin d'écrire le suffixe "Attribute". Conditionnel = ConditionalAttribute. Une classe d'attribut doit se terminer par "Attribute" mais peut être omise lorsqu'elle est utilisée comme attribut dans le code. Il est plus facile à lire lorsque le suffixe est omis.
Eric Ouellet

23

Vous pouvez essayer ceci si vous n'avez besoin que du code pour s'exécuter lorsque vous avez un débogueur attaché au processus.

if (Debugger.IsAttached)
{
     // do some stuff here
}

Je vous remercie! C'est exactement ce que je voulais: faire un Console.ReadLine () à la fin pour éviter de fermer la fenêtre de la console lors du débogage.
VVS

4

Je pense qu'il vaut peut-être la peine de mentionner que [ConditionalAttribute]c'est dans l' System.Diagnostics;espace de noms. J'ai un peu trébuché quand j'ai eu:

Error 2 The type or namespace name 'ConditionalAttribute' could not be found (are you missing a using directive or an assembly reference?)

après l'avoir utilisé pour la première fois (je pensais que ça l'aurait été System).


3

Si vous voulez savoir si le débogage, partout dans le programme. Utilisez ceci.

Déclarez la variable globale.

bool isDebug=false;

Créer une fonction pour vérifier le mode de débogage

[ConditionalAttribute("DEBUG")]
    public static void isDebugging()
    {
        isDebug = true;
    }

Dans la méthode initialize, appelez la fonction

isDebugging();

Maintenant dans tout le programme. Vous pouvez vérifier le débogage et effectuer les opérations. J'espère que cela t'aides!


1
AFAIK: ceci et ses variantes ne sont qu'un moyen sûr de savoir si un programme de lavage compilé avec l'indicateur de débogage défini.
LosManos
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.