C # si / entonces directivas para depuración vs liberación
-
21-09-2019 - |
Pregunta
propiedades en solución, he puesto configuración de "liberación" de mi único proyecto.
Al principio de la rutina principal, tengo este código, y que está mostrando el "Modo = depuración". También tengo estas dos líneas en la parte superior:
#define DEBUG
#define RELEASE
¿Estoy probando la variable de la derecha?
#if (DEBUG)
Console.WriteLine("Mode=Debug");
#elif (RELEASE)
Console.WriteLine("Mode=Release");
#endif
Mi objetivo es establecer diferentes valores por defecto para las variables sobre la base de depuración vs modo de lanzamiento.
Solución
Eliminar el #define DEBUG
en el código. Set preprocesadores en la configuración de generación para que específico de construcción (debug / _DEBUG deben definirse en VS ya).
La razón por la que se imprime "Modo = depuración" se debe a su #define
y luego se salta el elif
.
Además, la manera correcta de verificación es:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
No comprobar LIBERACIÓN
Otros consejos
De forma predeterminada, Visual Studio define DEBUG si el proyecto se compila en modo de depuración y no lo define si está en modo de lanzamiento. RELEASE no está definido en el modo de salida por defecto. Usar algo como esto:
#if DEBUG
// debug stuff goes here
#else
// release stuff goes here
#endif
Si usted quiere hacer algo sólo en modo de lanzamiento:
#if !DEBUG
// release...
#endif
Además, es importante señalar que se puede utilizar el atributo [Conditional("DEBUG")]
en los métodos que void
retorno a tenerlos solamente ejecutan si se define un determinado símbolo. El compilador eliminaría todas las llamadas a estos métodos, si no se define el símbolo:
[Conditional("DEBUG")]
void PrintLog() {
Console.WriteLine("Debug info");
}
void Test() {
PrintLog();
}
Yo prefiero comprobar como este vs buscando #defines:
if (System.Diagnostics.Debugger.IsAttached)
{
//...
}
else
{
//...
}
Con la advertencia de que, por supuesto, usted podría compilar y desplegar algo en el modo de depuración, pero todavía no tiene el depurador asociado.
No soy un gran fan de las cosas #if, especialmente si usted separa todo alrededor de su base de código, ya que le dará problemas en versiones de depuración pase, pero las versiones de lanzamiento fallar si no tienes cuidado.
Así que esto es lo que han llegado con (inspirado en #ifdef en C # ):
public interface IDebuggingService
{
bool RunningInDebugMode();
}
public class DebuggingService : IDebuggingService
{
private bool debugging;
public bool RunningInDebugMode()
{
//#if DEBUG
//return true;
//#else
//return false;
//#endif
WellAreWe();
return debugging;
}
[Conditional("DEBUG")]
private void WellAreWe()
{
debugging = true;
}
}
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
El método Debug.Assert
tiene DEBUG
atributo condicional. Si no está definido, la llamada y la asignación son isDebug = true
eliminado :
Si se define el símbolo, se incluye la llamada; de lo contrario, se omite la llamada (incluyendo la evaluación de los parámetros de la llamada).
Si se define DEBUG
, isDebug
se establece en true
(y se pasa a Debug.Assert
, que no hace nada en ese caso).
Si usted está tratando de utilizar la variable definida por el tipo de construcción debe quitar la dos líneas ...
#define DEBUG
#define RELEASE
... estos hará que el #if (PRUEBAS) para ser siempre verdad.
Además no es un símbolo de compilación condicional por defecto para Versión . Si desea definir una sola vez a las propiedades del proyecto, haga clic en el Build pestaña y luego añadir la liberación a los símbolos de compilación condicional cuadro de texto bajo el General rúbrica.
La otra opción sería la de hacer esto ...
#if DEBUG
Console.WriteLine("Debug");
#else
Console.WriteLine("Release");
#endif
Eliminar sus define en la parte superior
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
ligeramente modificado (bastarda?) Versión de la respuesta de Tod Thomson como una función estática en lugar de una clase separada (quería ser capaz de llamar en un formulario Web viewbinding de una clase viewutils que ya había incluido).
public static bool isDebugging() {
bool debugging = false;
WellAreWe(ref debugging);
return debugging;
}
[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
debugging = true;
}
NameSpace
using System.Resources;
using System.Diagnostics;
Método
private static bool IsDebug()
{
object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(DebuggableAttribute), false);
if ((customAttributes != null) && (customAttributes.Length == 1))
{
DebuggableAttribute attribute = customAttributes[0] as DebuggableAttribute;
return (attribute.IsJITOptimizerDisabled && attribute.IsJITTrackingEnabled);
}
return false;
}
Un consejo que usted puede ahorrar mucho tiempo - no hay que olvidar que, incluso si decide debug
bajo la configuración de generación (en vs2012 / 13 Menú está bajo BUILD => MANAGER CONFIGURATION) - eso no es suficiente.
Es necesario prestar atención a la Configuration
PUBLICAR, como por ejemplo:
Dado que el propósito de estas directivas del compilador son para decirle al compilador que no incluya el código, el código de depuración, código beta, o tal vez el código que se necesita por todos sus usuarios finales, excepto decir los que el departamento de publicidad, es decir, #Define AdDept usted quiere ser capaz de incluir o eliminarlos en función de sus necesidades. Sin tener que cambiar su código fuente si por ejemplo una fusiones no AdDept en el AdDept. Entonces todo lo que hay que hacer es incluir la directiva #AdDept en la página de opciones de propiedades compilador de una versión existente del programa y hacer una compilación y la wa! el código del programa resultante de la fusión nace vivo!.
También puede ser que desee utilizar un declarativo para un nuevo proceso que no está listo para el prime time o que no pueden estar activos en el código hasta que sea hora para liberarlo.
De todos modos, esa es la manera de hacerlo.
Me puse a pensar en una mejor manera. Me di cuenta de que los bloques son #if comenta con eficacia en otras configuraciones (suponiendo DEBUG
o RELEASE
; pero cierto con cualquier símbolo)
public class Mytest
{
public DateTime DateAndTimeOfTransaction;
}
public void ProcessCommand(Mytest Command)
{
CheckMyCommandPreconditions(Command);
// do more stuff with Command...
}
[Conditional("DEBUG")]
private static void CheckMyCommandPreconditions(Mytest Command)
{
if (Command.DateAndTimeOfTransaction > DateTime.Now)
throw new InvalidOperationException("DateTime expected to be in the past");
}
Eliminar las definiciones y comprobar si el condicional está en modo de depuración. No es necesario comprobar si la directiva está en modo de lanzamiento.
Algo como esto:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif