Código de "solo depuración" que debe ejecutarse solo cuando está "activado"

93

Me gustaría agregar un código C # de "solo depuración" que solo se ejecuta si la persona que realiza la depuración lo solicita. En C ++, solía hacer algo similar a lo siguiente:

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

No puedo hacer exactamente lo mismo en C # ya que no hay estática local.

Pregunta : ¿Cuál es la mejor manera de lograr esto en C #?

  1. ¿Debo usar un campo estático de clase privada con directivas de preprocesador de C # ( #if/#endif DEBUG)?
  2. ¿Debo usar el atributo condicional (para contener el código) y luego un campo estático de clase privada ( no rodeado por directivas de preprocesador de C # #if/#endif DEBUG?).
  3. ¿Algo más?
Matt Smith
fuente

Respuestas:

145

Una variable de instancia probablemente sería la forma de hacer lo que quieras. Puede hacer que sea estático para persistir el mismo valor durante la vida del programa (o subproceso dependiendo de su modelo de memoria estática), o convertirlo en una instancia var ordinaria para controlarlo durante la vida de una instancia de objeto. Si esa instancia es un singleton, se comportarán de la misma manera.

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

Para ser completo, los pragmas (directivas de preprocesador) se consideran un poco complicados de usar para controlar el flujo del programa. .NET tiene una respuesta incorporada para la mitad de este problema, utilizando el atributo "Condicional".

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

Sin pragmas, mucho más limpio. La desventaja es que Conditional solo se puede aplicar a métodos, por lo que tendrá que lidiar con una variable booleana que no hace nada en una versión de lanzamiento. Como la variable existe únicamente para alternar desde el host de ejecución de VS, y en una versión de versión, su valor no importa, es bastante inofensiva.

KeithS
fuente
2
Finalmente, alguien que leyó toda la pregunta. Gracias, está bien, parecía una solución larga (tener que tener las dos secciones del preprocesador), pero quizás sea lo mejor que C # puede hacer por lo que quiero.
Matt Smith
6
meh. No llamaría a esto largo solo porque agrega dos líneas más de directiva de preprocesador.
KeithS
4
Bueno, muchas gracias Patrick, por rechazar una respuesta aceptada de 3 años a favor de una que no resuelve todo el problema. El atributo condicional solo evita que el método se ejecute en modos sin depuración. El OP no solo quería eso, sino también poder "activar" el código usando el depurador. Y la etiqueta de gokkor tal como se usa no se compilará.
KeithS
2
Tenga en cuenta que el preprocesador le indica si el programa se está compilando en modo de depuración, pero no si el depurador se está ejecutando.
Shane
65

Lo que estas buscando es

[ConditionalAttribute("DEBUG")]

atributo.

Si, por ejemplo, escribe un método como:

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

cualquier llamada que realice a este método dentro de su propio código solo se ejecutará en modo de depuración. Si construye su proyecto en modo de lanzamiento, incluso la llamada al "MyLovelyDebugInfoMethod" será ignorada y eliminada de su binario.

Ah, y una cosa más si está tratando de determinar si su código se está depurando actualmente o no en el momento de la ejecución, también es posible verificar si el proceso actual está enganchado por un JIT. Pero todo esto es otro caso. Publique un comentario si esto es lo que está tratando de hacer.

gokkor
fuente
3
Al usar Atributo, no es necesario que escriba el sufijo "Atributo". Condicional = ConditionalAttribute. Una clase de atributo debe terminar con "Atributo", pero se puede omitir cuando se usa como atributo en el código. Es más fácil de leer cuando se omite el sufijo.
Eric Ouellet
23

Puede probar esto si solo necesita que el código se ejecute cuando tiene un depurador adjunto al proceso.

if (Debugger.IsAttached)
{
     // do some stuff here
}
Wes
fuente
¡Gracias! Esto es exactamente lo que quería: hacer un Console.ReadLine () al final para evitar cerrar la ventana de la consola durante la depuración.
VVS
4

Creo que vale la pena mencionar que [ConditionalAttribute]está en el System.Diagnostics;espacio de nombres. Tropecé un poco cuando obtuve:

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

después de usarlo por primera vez (pensé que estaría en System).

XyberICE
fuente
3

Si desea saber si está depurando, en todas partes del programa. Utilizar este.

Declarar variable global.

bool isDebug=false;

Crear función para verificar el modo de depuración

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

En el método initialize llame a la función

isDebugging();

Ahora en todo el programa. Puede verificar la depuración y realizar las operaciones. ¡Espero que esto ayude!

Mohamed Alikhan
fuente
1
AFAIK: esto y sus variantes es la única forma segura de saber si un programa se ha compilado con el indicador de depuración establecido.
LosManos