#si de DEPURACIÓN vs Condicional("DEBUG")


Qué es mejor usar, y por qué, en un proyecto grande:

#if DEBUG
    public void SetPrivateValue(int value)
    { ... }
#endif

O

[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
Author: Osama AbuSitta, 2010-09-24

7 answers

Realmente depende de lo que estés buscando:{[14]]}

  • #if DEBUG: El código aquí ni siquiera llegará a la IL en el lanzamiento.
  • [Conditional("DEBUG")]: Este código llegará al IL, sin embargo las llamadas al método se omitirán a menos que se establezca DEBUG cuando se compile el llamante.

Personalmente utilizo ambos dependiendo de la situación:

Condicional ("DEBUG") Ejemplo: Uso esto para no tener que volver y editar mi código más tarde durante el lanzamiento, pero durante la depuración quiero estar seguro de que no hice ningún error tipográfico. Esta función comprueba que escribo un nombre de propiedad correctamente cuando intento usarlo en mis cosas INotifyPropertyChanged.

[Conditional("DEBUG")]
[DebuggerStepThrough]
protected void VerifyPropertyName(String propertyName)
{
    if (TypeDescriptor.GetProperties(this)[propertyName] == null)
        Debug.Fail(String.Format("Invalid property name. Type: {0}, Name: {1}",
            GetType(), propertyName));
}

Realmente no quieres crear una función usando #if DEBUG a menos que estés dispuesto a envolver cada llamada a esa función con el mismo #if DEBUG:

#if DEBUG
    public void DoSomething() { }
#endif

    public void Foo()
    {
#if DEBUG
        DoSomething(); //This works, but looks FUGLY
#endif
    }

Versus:

[Conditional("DEBUG")]
public void DoSomething() { }

public void Foo()
{
    DoSomething(); //Code compiles and is cleaner, DoSomething always
                   //exists, however this is only called during DEBUG.
}

#if DEBUG ejemplo: Uso esto cuando intento configurar diferentes enlaces para WCF comunicar.

#if DEBUG
        public const String ENDPOINT = "Localhost";
#else
        public const String ENDPOINT = "BasicHttpBinding";
#endif

En el primer ejemplo, todo el código existe, pero solo se ignora a menos que DEBUG esté activado. En el segundo ejemplo, el PUNTO FINAL const se establece en "Localhost" o "basicHttpBinding" dependiendo de si DEBUG está establecido o no.


Actualización: Estoy actualizando esta respuesta para aclarar un punto importante y complicado. Si elige usar ConditionalAttribute, tenga en cuenta que las llamadas se omiten durante la compilación, y no en tiempo de ejecución. Que is:

[13] MyLibrary.dll
[Conditional("DEBUG")]
public void A()
{
    Console.WriteLine("A");
    B();
}

[Conditional("DEBUG")]
public void B()
{
    Console.WriteLine("B");
}

Cuando la biblioteca se compila en modo release (es decir, sin símbolo de DEPURACIÓN), siempre se omitirá la llamada a B() desde A(), incluso si se incluye una llamada a A() porque la DEPURACIÓN está definida en el ensamblado que llama.

 510
Author: m-y,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-28 15:23:14

Bueno, vale la pena señalar que no significan lo mismo en absoluto.

Si el símbolo de DEPURACIÓN no está definido, entonces en el primer caso no se llamará a SetPrivateValue... mientras que en el segundo caso existirá, pero cualquier llamadores que se compilen sin el símbolo de DEPURACIÓN tendrán esas llamadas omitidas.

Si el código y todos sus llamadores están en el mismo ensamblado, esta diferencia es menos importante, pero significa que en el primer caso también necesita tenga #if DEBUG alrededor del código que llama también.

Personalmente recomendaría el segundo enfoque, pero necesitas mantener la diferencia entre ellos clara en tu cabeza.

 59
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-24 15:37:51

Estoy seguro de que muchos no estarán de acuerdo conmigo, pero después de haber pasado tiempo como un tipo de construcción constantemente escuchando " Pero funciona en mi máquina!", Tomo el punto de vista de que casi nunca debe utilizar cualquiera. Si realmente necesita algo para probar y depurar, encuentre una manera de hacer que la capacidad de prueba se separe del código de producción real.

Resumen los escenarios con burla en pruebas unitarias, haga versiones únicas de las cosas para escenarios únicos que desea probar, pero no ponga pruebas para depure en el código de los binarios que prueba y escribe para la versión de producción. Estas pruebas de depuración solo ocultan posibles errores de los desarrolladores para que no se encuentren hasta más adelante en el proceso.

 40
Author: Jimmy Hoffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-08 11:04:22

Este también puede ser útil:

if (Debugger.IsAttached)
{
...
}
 10
Author: sofsntp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-30 12:57:19

Con el primer ejemplo, SetPrivateValue no existe en la build si DEBUG no está definido, con el segundo ejemplo, llamadas a SetPrivateValue no existe en la build si DEBUG no está definido.

Con el primer ejemplo, tendrás que envolver cualquier llamada a SetPrivateValue con #if DEBUG también.

Con el segundo ejemplo, se omitirán las llamadas a SetPrivateValue, pero tenga en cuenta que SetPrivateValue todavía se compilará. Esto es útil si está creando una biblioteca, por lo que una aplicación que haga referencia a su la biblioteca todavía puede usar su función (si se cumple la condición).

Si desea omitir las llamadas y ahorrar el espacio del llamante, podría usar una combinación de las dos técnicas:

[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value){
    #if DEBUG
    // method body here
    #endif
}
 9
Author: P Daddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-24 17:13:50

Supongamos que su código también tenía una instrucción #else que definía una función stub nula, abordando uno de los puntos de Jon Skeet. Hay una segunda distinción importante entre los dos.

Supongamos que la función #if DEBUG o Conditional existe en una DLL a la que hace referencia el ejecutable principal del proyecto. Usando #if, la evaluación del condicional se realizará con respecto a la configuración de compilación de la biblioteca. Usando el atributo Conditional, la evaluación del condicional será realizado con respecto a la configuración de compilación del invocador.

 4
Author: Kennet Belenky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-15 18:39:46

Tengo una extensión SOAP WebService para registrar el tráfico de red usando un [TraceExtension] personalizado. Uso esto solo para compilaciones de depuración y omito las compilaciones de versiones. Use el # if DEBUG para envolver el atributo [TraceExtension] y eliminarlo de las compilaciones de Release.

#if DEBUG
[TraceExtension]
#endif
[System.Web.Service.Protocols.SoapDocumentMethodAttribute( ... )]
[ more attributes ...]
public DatabaseResponse[] GetDatabaseResponse( ...) 
{
    object[] results = this.Invoke("GetDatabaseResponse",new object[] {
          ... parmeters}};
}

#if DEBUG
[TraceExtension]
#endif
public System.IAsyncResult BeginGetDatabaseResponse(...)

#if DEBUG
[TraceExtension]
#endif
public DatabaseResponse[] EndGetDatabaseResponse(...)
 1
Author: Steven J. Hathaway,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-09 04:49:56