web-dev-qa-db-fra.com

Code "débogage uniquement" qui ne doit être exécuté que lorsque "activé"

Je voudrais ajouter un code C # "debug only" qui ne s’exécute que si la personne le débogage 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: Quel est le meilleur moyen d'accomplir cela en C #?

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

Une variable d'instance serait probablement le moyen de faire ce que vous voulez. Vous pouvez rendre statique la persistance de la même valeur pendant toute la vie du programme (ou du thread en fonction de votre modèle de mémoire statique), ou en faire une instance ordinaire var pour le 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
 // ...
}

Pour être tout à fait complet, les pragmas (directives de pré-traitement) sont considérés un peu comme un kludge à utiliser pour contrôler le déroulement 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 validée. Étant donné que la variable existe uniquement pour être basculée à partir de l'hôte d'exécution VS, et que peu importe sa valeur dans la construction d'une version, elle est plutôt inoffensive.

130
KeithS

Ce que tu recherches, 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 effectuez à cette méthode dans votre propre code ne sera exécuté qu'en mode débogage. Si vous construisez votre projet en mode release, même l'appel à "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 en cours est accroché à un JIT. Mais tout cela est un autre cas. Postez un commentaire si c’est ce que vous essayez de faire.

59
gokkor

Vous pouvez essayer ceci si vous avez seulement besoin du code à exécuter lorsque vous avez un débogueur attaché au processus.

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

Je pense qu'il peut être intéressant de mentionner que [ConditionalAttribute] Est dans l'espace de noms System.Diagnostics;. Je suis tombé un peu 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 cela aurait été dans System).

3
XyberICE

Si vous voulez savoir s'il s'agit d'un débogage, partout dans le programme. Utilisez ceci.

Déclarez la variable globale.

bool isDebug=false;

Fonction de création permettant de vérifier le mode 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!

3
Mohamed Alikhan