Codice "Solo debug" che dovrebbe essere eseguito solo quando "attivato"


93

Vorrei aggiungere del codice C # "solo debug" che viene eseguito solo se la persona che esegue il debug lo richiede. In C ++, facevo qualcosa di simile al seguente:

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
 // ...
}

Non posso fare esattamente lo stesso in C # poiché non esiste una statica locale.

Domanda : qual è il modo migliore per eseguire questa operazione in C #?

  1. Devo usare un campo statico di classe privata con direttive del preprocessore C # (#if/#endif DEBUG )?
  2. Devo usare l'attributo condizionale (per contenere il codice) e quindi un campo statico di classe privata ( non circondato dalle direttive del preprocessore C ##if/#endif DEBUG ?).
  3. Qualcos'altro?

Risposte:


145

Una variabile di istanza sarebbe probabilmente il modo per fare ciò che vuoi. Potresti renderlo statico per mantenere lo stesso valore per la vita del programma (o thread a seconda del tuo modello di memoria statica), o renderlo un'istanza ordinaria var per controllarlo sulla vita di un'istanza di un oggetto. Se quell'istanza è un singleton, si comporteranno allo stesso modo.

#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
 // ...
}

Per essere completi, i pragma (direttive del preprocessore) sono considerati un po 'un kludge da usare per controllare il flusso del programma. .NET ha una risposta incorporata per metà di questo problema, utilizzando l'attributo "Conditional".

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.
  }    
  // ...
}

Nessun pragma, molto più pulito. Lo svantaggio è che Conditional può essere applicato solo ai metodi, quindi dovrai gestire una variabile booleana che non fa nulla in una build di rilascio. Poiché la variabile esiste esclusivamente per essere commutata dall'host di esecuzione VS e in una build di rilascio il suo valore non ha importanza, è abbastanza innocuo.


2
Infine, qualcuno che ha letto l' intera domanda. Grazie, okay - sembrava una specie di soluzione lunga (dover avere le due sezioni del preprocessore), ma forse è il meglio che C # possa fare per quello che voglio.
Matt Smith

6
meh. Non lo definirei lungo solo perché aggiungi altre due righe di direttiva per il preprocessore.
KeithS

4
Bene, grazie mille Patrick, per aver votato negativamente una risposta accettata di 3 anni a favore di una che non risolve l'intero problema. L'attributo condizionale impedisce solo l'esecuzione del metodo in modalità non di debug. L'OP voleva non solo quello, ma essere in grado di "attivare" il codice usando il debugger. E il tag di gokkor usato non verrà compilato.
KeithS

2
Nota che il preprocessore ti dice se il programma sta compilando in modalità debug, ma non se il debugger è effettivamente in esecuzione.
Shane

65

Quello che stai cercando è

[ConditionalAttribute("DEBUG")]

attributo.

Se ad esempio scrivi un metodo come:

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

qualsiasi chiamata effettuata a questo metodo all'interno del proprio codice verrà eseguita solo in modalità di debug. Se crei il tuo progetto in modalità di rilascio, anche la chiamata a "MyLovelyDebugInfoMethod" verrà ignorata e scaricata dal tuo binario.

Oh, e ancora una cosa se stai cercando di determinare se il tuo codice è attualmente in fase di debug al momento dell'esecuzione, è anche possibile controllare se il processo corrente è agganciato da un JIT. Ma questo è tutto insieme un altro caso. Pubblica un commento se questo è ciò che stai cercando di fare.


3
Quando si utilizza Attribute, non è necessario scrivere il suffisso "Attribute". Conditional = ConditionalAttribute. Una classe di attributi dovrebbe terminare con "Attribute" ma potrebbe essere omessa se utilizzata come attributo nel codice. È più facile da leggere quando il suffisso viene omesso.
Eric Ouellet

23

Puoi provare questo se hai solo bisogno del codice da eseguire quando hai un debugger collegato al processo.

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

Grazie! Questo è esattamente quello che volevo: fare un Console.ReadLine () alla fine per impedire la chiusura della finestra della console durante il debug.
VVS

4

Penso che possa valere la pena ricordare che [ConditionalAttribute]è nello System.Diagnostics;spazio dei nomi. Sono inciampato un po 'quando ho ottenuto:

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

dopo averlo usato per la prima volta (pensavo che sarebbe stato in System).


3

Se vuoi sapere se si esegue il debug, ovunque nel programma. Usa questo.

Dichiara la variabile globale.

bool isDebug=false;

Crea una funzione per controllare la modalità di debug

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

Nel metodo initialize chiama la funzione

isDebugging();

Ora nell'intero programma. Puoi controllare il debug ed eseguire le operazioni. Spero che questo ti aiuti!


1
AFAIK: questo e le sue varianti sono solo un modo infallibile per sapere se un programma è stato compilato con il flag di debug impostato.
LosManos
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.