Cuál 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)
{ ... }
c#
debugging
preprocessor
debug-symbols
Lucas B
fuente
fuente
Respuestas:
Realmente depende de lo que estés buscando:
#if DEBUG
: El código aquí ni siquiera llegará al IL en el lanzamiento.[Conditional("DEBUG")]
: Este código alcanzará el IL, sin embargo , se omitirán las llamadas al método a menos que se defina DEBUG cuando se compila la persona que llama.Personalmente uso ambos dependiendo de la situación:
Ejemplo condicional ("DEPURACIÓN"): Utilizo esto para no tener que volver atrás 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 mi material INotifyPropertyChanged.
Realmente no desea crear una función utilizando a
#if DEBUG
menos que esté dispuesto a ajustar cada llamada a esa función con el mismo#if DEBUG
:versus:
#if DEBUG ejemplo: lo uso cuando intento configurar diferentes enlaces para la comunicación WCF.
En el primer ejemplo, todo el código existe, pero solo se ignora a menos que DEBUG esté activado. En el segundo ejemplo, el const ENDPOINT se establece en "Localhost" o "BasicHttpBinding" dependiendo de si DEBUG está configurado o no.
Actualización: estoy actualizando esta respuesta para aclarar un punto importante y complicado. Si elige usar el
ConditionalAttribute
, tenga en cuenta que las llamadas se omiten durante la compilación, y no el tiempo de ejecución . Es decir:MyLibrary.dll
Cuando la biblioteca se compila contra el modo de liberación (es decir, sin símbolo DEPURACIÓN), siempre se omitirá la llamada
B()
desde adentroA()
, incluso siA()
se incluye una llamada a porque DEBUG está definido en el ensamblado de la llamada.fuente
Bueno, vale la pena señalar que no significan lo mismo en absoluto.
Si el símbolo DEBUG no está definido, entonces en el primer caso
SetPrivateValue
no se llamará a sí mismo ... mientras que en el segundo caso existirá, pero las llamadas que se compilan sin el símbolo DEBUG tendrán esas llamadas omitidas.Si el código y todas las personas que llaman están en el mismo ensamblado, esta diferencia es menos importante, pero significa que en el primer caso también debe tener
#if DEBUG
alrededor del código de llamada .Personalmente, recomendaría el segundo enfoque, pero debe mantener clara la diferencia entre ellos.
fuente
Estoy seguro de que muchas personas estarán en desacuerdo conmigo, pero después de haber pasado tiempo como un tipo de compilación constantemente escuchando "¡Pero funciona en mi máquina!", Considero que tampoco deberías usarlo. Si realmente necesita algo para probar y depurar, encuentre una manera de hacer que esa capacidad de prueba se separe del código de producción real.
Resuma los escenarios con burlas en las pruebas unitarias, haga versiones únicas de las cosas para los escenarios únicos que desea probar, pero no ponga pruebas de depuración 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.
fuente
#if debug
o una construcción similar en su código?#if DEBUG
para que no enviemos spam accidentalmente a otros mientras probamos un sistema que debe transmitir correos electrónicos como parte del proceso. A veces estas son las herramientas adecuadas para el trabajo :)Este también puede ser útil:
fuente
Debugger.IsAttached
debe invocar en tiempo de ejecución incluso en versiones de lanzamiento.Con el primer ejemplo,
SetPrivateValue
no existirá en la compilación siDEBUG
no está definido, con el segundo ejemplo, las llamadas aSetPrivateValue
no existirán en la compilación siDEBUG
no está definido.Con el primer ejemplo, usted tiene que envolver cualquier llamada a
SetPrivateValue
la#if DEBUG
también.Con el segundo ejemplo,
SetPrivateValue
se omitirán las llamadas a , pero tenga en cuenta queSetPrivateValue
aún se compilará. Esto es útil si está creando una biblioteca, por lo que una aplicación que haga referencia a su biblioteca aún puede usar su función (si se cumple la condición).Si desea omitir las llamadas y guardar el espacio de la persona que llama, puede utilizar una combinación de las dos técnicas:
fuente
#if DEBUG
alrededorConditional("DEBUG")
no elimina las llamadas a esta función, sólo se elimina la función de IL alltogether, por lo que todavía tiene las llamadas a función que no existen (errores de compilación).Supongamos que su código también tenía una
#else
declaración que definía una función de código auxiliar nulo, abordando uno de los puntos de Jon Skeet. Hay una segunda distinción importante entre los dos.Suponga que la función
#if DEBUG
oConditional
existe en una DLL a la que hace referencia el ejecutable de su proyecto principal. Usando#if
, la evaluación del condicional se realizará con respecto a la configuración de compilación de la biblioteca. Usando elConditional
atributo, la evaluación del condicional se realizará con respecto a la configuración de compilación del invocador.fuente
Tengo una extensión SOAP WebService para registrar el tráfico de red usando una costumbre
[TraceExtension]
. Lo uso solo para las versiones de depuración y omito las versiones de lanzamiento . Use#if DEBUG
para envolver el[TraceExtension]
atributo y así eliminarlo de las versiones de lanzamiento .fuente
Por lo general, lo necesitaría en Program.cs, donde desea decidir ejecutar el código Debug on Non-Debug y eso también principalmente en los Servicios de Windows. Así que creé un campo de solo lectura IsDebugMode y establecí su valor en el constructor estático como se muestra a continuación.
fuente