C# se/então directivas para depuração vs lançamento
-
21-09-2019 - |
Pergunta
Em propriedades da Solução, tenho que o conjunto de Configuração para "lançamento" para o meu primeiro e único projeto.
No início da rotina principal, eu tenho este código, e ele está mostrando o Modo "=Debug".Eu também tenho essas duas linhas no topo:
#define DEBUG
#define RELEASE
Estou testando o direito de variável?
#if (DEBUG)
Console.WriteLine("Mode=Debug");
#elif (RELEASE)
Console.WriteLine("Mode=Release");
#endif
O meu objetivo é definir padrões diferentes para variáveis com base na depuração vs modo de edição.
Solução
Remover o #define DEBUG
no seu código.Conjunto de preprocessadores na configuração de compilação para compilação específica (DEBUG/_DEBUG deve ser definido no VS já).
A razão pela qual ele imprime "Modo=Debug" é por causa do seu #define
e, em seguida, ignora o elif
.
Além disso, o direito de forma a verificar é:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
Não olhe para o LANÇAMENTO
Outras dicas
Por padrão, o Visual Studio define DEBUG, se o projeto é compilado em modo de Depuração e não definem se ele está em modo de edição.LANÇAMENTO não está definida no modo de edição por padrão.Usar algo como isto:
#if DEBUG
// debug stuff goes here
#else
// release stuff goes here
#endif
Se você quer fazer algo apenas no modo de edição:
#if !DEBUG
// release...
#endif
Além disso, vale ressaltar que você pode usar [Conditional("DEBUG")]
atributo em métodos que retornam void
para tê-los executado somente se um determinado símbolo é definido.O compilador iria remover todas as chamadas para esses métodos se o símbolo não estiver definido:
[Conditional("DEBUG")]
void PrintLog() {
Console.WriteLine("Debug info");
}
void Test() {
PrintLog();
}
Eu prefiro a verificar como esta vs procurando #define:
if (System.Diagnostics.Debugger.IsAttached)
{
//...
}
else
{
//...
}
Com a ressalva de que, claro, você pode compilar e implantar algo no modo de depuração, mas ainda não tem o depurador anexado.
Eu não sou um grande fã do #se as coisas, especialmente se você espalhar tudo em torno de sua base de código, como ele vai te dar problemas onde compilações de Depuração passar, mas compilações de falhar se você não tiver cuidado.
Então aqui está o que eu vim com o (inspirado #ifdef em 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 '=='
O método Debug.Assert
tem condicional atributo DEBUG
.Se não for definido, a chamada e a atribuição de isDebug = true
são eliminado:
Se o símbolo é definido, a chamada será incluído;caso contrário, a chamada (incluindo a avaliação dos parâmetros de chamada) é omitido.
Se DEBUG
é definido, isDebug
é definido como true
(e passou a Debug.Assert
, que nada faz, nesse caso).
Se você está tentando usar a variável definida para o tipo de compilação que você deve remover as duas linhas ...
#define DEBUG
#define RELEASE
...estes irão causar o #if (DEBUG) para ser sempre verdadeiro.
Também não há um padrão de compilação Condicional símbolo para LANÇAMENTO.Se você deseja definir um vá para as propriedades do projeto, clique no Construir guia e, em seguida, adicionar a LIBERTAÇÃO para o Símbolos de compilação condicional caixa de texto sob a Geral o título.
A outra opção seria fazer isso...
#if DEBUG
Console.WriteLine("Debug");
#else
Console.WriteLine("Release");
#endif
Remover o define no topo
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif
Ligeiramente modificado (bastardized?) versão de a resposta por Tod Thomson como uma função estática, ao invés de incluir uma classe separada (eu queria ser capaz de chamá-lo em um Formulário da web viewbinding a partir de um viewutils classe eu já tinha incluído).
public static bool isDebugging() {
bool debugging = false;
WellAreWe(ref debugging);
return debugging;
}
[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
debugging = true;
}
Espaço de nomes
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;
}
Uma dica que pode te salvar um monte de tempo - não se esqueça de que, mesmo se você escolher debug
sob a configuração de compilação (no vs2012/13 menu é em CONSTRUIR => CONFIGURATION MANAGER) - que não é o suficiente.
Você precisa prestar atenção para o PUBLICAR Configuration
, como tal:
Uma vez que o objetivo destas diretivas de COMPILADOR são para dizer ao compilador NÃO incluir o código, depuração de código,código beta, ou, talvez, o código que é necessário para todos os seus usuários finais, exceto dizer que aqueles que o departamento de publicidade, i.é.#Define AdDept você quer ser capaz de incluir ou removê-los com base em suas necessidades.Sem ter que mudar seu código-fonte se, por exemplo, não AdDept se funde com o AdDept.Em seguida, tudo o que precisa ser feito é incluir o #AdDept directiva no compilador de página de propriedades opções de uma versão existente do programa e fazer uma compilação e wa la!mesclado de código do programa nascentes vivas!.
Você também pode querer usar um declarativa para um novo processo que não está pronto para o horário nobre ou que não pode ser ativa no código até que é hora de liberá-lo.
De qualquer maneira, essa é a maneira que eu faço.
Eu tenho que pensar em uma maneira melhor.Ocorreu-me que o #caso os blocos sejam efetivamente comentários em outras configurações (supondo que DEBUG
ou RELEASE
;mas é verdade com qualquer 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");
}
Remover as definições e verifique se a condicional é no modo de depuração.Você não precisa verificar se a diretiva estiver em modo de edição.
Algo como isto:
#if DEBUG
Console.WriteLine("Mode=Debug");
#else
Console.WriteLine("Mode=Release");
#endif