2009-09-17 13 views
9

È possibile creare un metodo che esegue l'assistenza per il debug come la classe System.Diagnostics.Debug?È possibile creare un metodo Debug-only in .NET?

Sto cercando un modo per costruire un metodo che quando viene chiamato da un assembly compilato con il simbolo di compilazione condizionale DEBUG definito, restituisce un'operazione e che è un no-op quando viene chiamato da un assembly senza il simbolo definito.

Se possibile, mi piacerebbe che le chiamate ai metodi di debug aggiungessero un sovraccarico minimo o aumentassero di dimensioni alla versione di rilascio dell'assieme.

Per chiarire, i metodi di debug devono essere in un assembly compilato in modalità di rilascio. Le chiamate ai metodi dovrebbero generare solo le operazioni quando vengono chiamate da un assembly con il simbolo DEBUG definito nell'ambito della chiamata al metodo.

risposta

30

aggiungere il Conditional attribuiscono al metodo, in questo modo:

[Conditional("DEBUG")] 
public void Whatever() { 
    //... 
} 

noti che esimo Il metodo deve restituire void e non può avere alcun parametro out; altrimenti, sarebbe impossibile rimuovere una chiamata.

Il metodo verrà compilato nell'assieme, ma i compilatori conformi a CLS emetteranno solo chiamate al metodo se gli assembly che stanno compilando DEBUG è definito. Si noti che il compilatore C++ non è conforme a CLS e emetterà sempre la chiamata.

+0

+1 per aver ricordato che condizionale non è infallibile (vuol dire che è ancora CLI-compatibile?) Cosa succede per C++ chiama a Debug.WriteLine? È per tutte le versioni? Sarebbe bello modificarlo in: P –

+0

Non l'ho ancora provato. La pagina MSDN su ConditionalAttribute dice solo che il compilatore C++ non è conforme, senza dire quali versioni. – SLaks

+0

Come ho affermato nella risposta ('e emetterà sempre la chiamata '), il compilatore C++ (credo) emetterà sempre chiamate a' WriteLine', anche in Release. – SLaks

3

Se si smonta classe System.Diagnostics.Debug utilizzando Reflector si può vedere che questo viene fatto utilizzando l'attributo [Conditional("DEBUG")]:

public sealed class Debug 
{ 
    private Debug(); 
    [Conditional("DEBUG")] 
    public static void Assert(bool condition); 
    // etc... 
} 
1

Se avete bisogno di un'altra firma di func vuoto (..) senza parametri fuori, quello che sarebbe sbagliato con

MyDebugObject Foo(out int justForGrins) 
{ 
    justForGrins = <safe value for release builds>; 
    MyDebugObject result = <safe value for release builds>; 
    #if DEBUG 
    .. run code you need for your debugging... 
    #endif 
    return result; 
} 

e 'più prolisso e meno elegante rispetto al ConditionalAttribute, ma permetterebbe una firma più flessibile.

0

Perché non provare qualcosa di simile?

#if DEBUG 
     private void DebugLog(string message) 
     { 
      // do whatever u want. 
     } 
#endif 
+0

Ciò crea un problema in cui il metodo non esiste durante la compilazione in una build non di debug.Qualsiasi codice che tenta di chiamare questo metodo non verrà quindi compilato. La classe 'Debug' ha metodi che puoi chiamare dal codice di debug, ma a cui le chiamate vengono rimosse durante la compilazione del codice di rilascio. –

+0

@Tragedian - ooPS! –

+0

@Tragedian Anche con i problemi che hai citato questo può essere una soluzione superiore in alcune circostanze. Questa è una risposta valida finché ciò che hai menzionato viene preso in considerazione. –

Problemi correlati