2009-09-17 18 views
9

¿Es posible crear un método que realice la asistencia de depuración como la clase System.Diagnostics.Debug?¿Es posible crear un método de solo depuración en .NET?

Estoy buscando una forma de construir un método que cuando es llamado por un ensamblado compilado con el símbolo de compilación condicionado DEBUG definido, da como resultado una operación, y que es no-operativa cuando es invocado por un ensamble sin el símbolo definido.

Si es posible, me gustaría que sea posible que las llamadas a los métodos de depuración agreguen una sobrecarga mínima o aumenten el tamaño de la versión de lanzamiento del ensamblaje.

Para aclarar, los métodos de depuración deben estar en un ensamblado compilado en modo Release. Las llamadas a los métodos solo deberían generar operaciones cuando se las llama desde un ensamblado con el símbolo DEPURAR definido en el alcance de la llamada al método.

Respuesta

30

Añadir la Conditional atribuyen al método, como esto:

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

Tenga en cuenta que º El método debe devolver void, y no puede tener ningún parámetro out; de lo contrario, sería imposible eliminar una llamada.

El método se compilará en el ensamblado, pero los compiladores que cumplen con CLS solo emitirán llamadas al método si los ensamblados que están compilando tienen DEBUG definido. Tenga en cuenta que el compilador C++ no es compatible con CLS y siempre emitirá la llamada.

+0

+1 por señalar que el condicional no es a prueba de tontos (¿significa que es incluso CLI compatible?) ¿Qué ocurre para C++ llama a Debug.WriteLine? Es eso para todas las versiones? Sería bueno que edites eso en: P –

+0

No lo he intentado. La página de MSDN en ConditionalAttribute solo dice que el compilador de C++ no es compatible, sin decir qué versiones. – SLaks

+0

Como dije en la respuesta ('y siempre emitiré la llamada'), el compilador de C++ (creo) siempre emitirá llamadas a' WriteLine', incluso en Release. – SLaks

3

Si desmonta la clase System.Diagnostics.Debug usando Reflector se puede ver que esto se hace mediante el atributo [Conditional("DEBUG")]:

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

Si necesita otra firma de func vacío (..) sin parámetros out, lo que sería malo en

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; 
} 

es más detallado y menos elegante que el ConditionalAttribute, sino que le permitiría a una firma más flexible.

0

¿Por qué no probar algo como esto?

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

Esto crea un problema donde el método no existe cuando se compila en una compilación sin depuración.Cualquier código que intente llamar a este método no se compilará. La clase 'Debug' tiene métodos a los que se puede llamar desde el código de depuración, pero a los cuales se eliminan las llamadas cuando se compila el código de la versión. –

+0

@Tragedian - ¡ooPS! –

+0

@Tragedian Incluso con los problemas que menciona, esta puede ser una solución superior en algunas circunstancias. Esta es una respuesta válida siempre que se tenga en cuenta lo que usted mencionó. –

Cuestiones relacionadas