Qual é melhor usar e por que, em um projeto grande:
#if DEBUG
public void SetPrivateValue(int value)
{ ... }
#endif
ou
[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value)
{ ... }
c#
debugging
preprocessor
debug-symbols
Lucas B
fonte
fonte
Respostas:
Realmente depende do que você procura:
#if DEBUG
: O código aqui nem chegará à IL no lançamento.[Conditional("DEBUG")]
: Este código alcançará o IL, no entanto, as chamadas para o método serão omitidas, a menos que DEBUG seja definido quando o chamador for compilado.Pessoalmente, uso os dois, dependendo da situação:
Exemplo condicional ("DEBUG"): Eu uso isso para não precisar voltar e editar meu código posteriormente durante o lançamento, mas durante a depuração, quero ter certeza de que não fiz nenhum erro de digitação. Essa função verifica se eu digito um nome de propriedade corretamente ao tentar usá-lo no meu material INotifyPropertyChanged.
Você realmente não deseja criar uma função usando, a
#if DEBUG
menos que esteja disposto a encerrar todas as chamadas dessa função com a mesma#if DEBUG
:versus:
#if Exemplo de DEBUG: eu uso isso ao tentar configurar ligações diferentes para a comunicação WCF.
No primeiro exemplo, todo o código existe, mas é apenas ignorado, a menos que DEBUG esteja ativado. No segundo exemplo, o const ENDPOINT é definido como "Localhost" ou "BasicHttpBinding", dependendo se DEBUG estiver definido ou não.
Atualização: Estou atualizando esta resposta para esclarecer um ponto importante e complicado. Se você optar por usar o
ConditionalAttribute
, lembre-se de que as chamadas são omitidas durante a compilação e não o tempo de execução . Isso é:MyLibrary.dll
Quando a biblioteca é compilada contra o modo de versão (ou seja, nenhum símbolo de depuração), ele sempre terá a chamada para
B()
dentroA()
omitido, mesmo se uma chamada paraA()
está incluído porque DEBUG é definido na chamar montagem.fonte
Bem, vale a pena notar que eles não significam a mesma coisa.
Se o símbolo DEBUG não estiver definido, no primeiro caso, o
SetPrivateValue
próprio não será chamado ... enquanto no segundo caso existir, mas todos os chamadores que são compilados sem o símbolo DEBUG terão essas chamadas omitidas.Se o código e todos os seus chamadores estiverem no mesmo assembly, essa diferença será menos importante - mas isso significa que, no primeiro caso, você também precisará ter também
#if DEBUG
o código de chamada .Pessoalmente, eu recomendaria a segunda abordagem - mas você precisa manter clara a diferença entre elas.
fonte
Tenho certeza de que muitos discordarão de mim, mas, tendo passado algum tempo como profissional de construção ouvindo constantemente "Mas funciona na minha máquina!", Entendo que você também nunca deve usar isso. Se você realmente precisa de algo para teste e depuração, descubra uma maneira de tornar essa testabilidade separada do código de produção real.
Abstraia os cenários com zombaria nos testes de unidade, faça versões únicas dos itens para os cenários que você deseja testar, mas não coloque testes de depuração no código dos binários que você testa e escreve para o release de produção. Esses testes de depuração apenas ocultam possíveis erros dos desenvolvedores, para que não sejam encontrados até mais tarde no processo.
fonte
#if debug
ou qualquer construção semelhante em seu código?#if DEBUG
para não enviar spam acidentalmente a outros enquanto testamos um sistema que deve transmitir emails como parte do processo. Às vezes, essas são as ferramentas certas para o trabalho :)Este também pode ser útil:
fonte
Debugger.IsAttached
deve ser chamado em tempo de execução, mesmo nas versões do release.Com o primeiro exemplo,
SetPrivateValue
não existirá na compilação seDEBUG
não estiver definido, com o segundo exemplo, chamadas paraSetPrivateValue
não existirão na compilação seDEBUG
não estiver definido.Com o primeiro exemplo, você vai ter que envolver todas as chamadas para
SetPrivateValue
com#if DEBUG
tão bem.Com o segundo exemplo, as chamadas para
SetPrivateValue
serão omitidas, mas saiba queSetPrivateValue
elas ainda serão compiladas. Isso é útil se você estiver criando uma biblioteca, para que um aplicativo que faça referência à sua biblioteca ainda possa usar sua função (se a condição for atendida).Se você deseja omitir as chamadas e economizar o espaço do chamado, você pode usar uma combinação das duas técnicas:
fonte
#if DEBUG
ContornarConditional("DEBUG")
não remove as chamadas para essa função, apenas remove a função da IL completamente, então você ainda está tendo chamadas para a função que não existe (erros de compilação).Vamos supor que seu código também tenha uma
#else
instrução que definiu uma função de stub nulo, abordando um dos pontos de Jon Skeet. Há uma segunda distinção importante entre os dois.Suponha que a função
#if DEBUG
ouConditional
exista em uma DLL referenciada pelo executável do projeto principal. Usando o#if
, a avaliação do condicional será realizada com relação às configurações de compilação da biblioteca. Usando oConditional
atributo, a avaliação do condicional será realizada com relação às configurações de compilação do invocador.fonte
Eu tenho uma extensão SOAP WebService para registrar o tráfego de rede usando um costume
[TraceExtension]
. Eu uso isso apenas para compilações de depuração e omitir das compilações de versão . Use o#if DEBUG
para quebrar o[TraceExtension]
atributo, removendo-o das compilações do Release .fonte
Normalmente, você precisaria dele em Program.cs, onde deseja decidir executar o código Debug on Non-Debug e principalmente nos Serviços do Windows. Então, criei um campo somente leitura IsDebugMode e defina seu valor no construtor estático, como mostrado abaixo.
fonte