Lequel est préférable d'utiliser, et pourquoi, sur un grand projet:
#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
la source
la source
Réponses:
Cela dépend vraiment de ce que vous recherchez:
#if DEBUG
: Le code ici n'atteindra même pas l'IL à sa sortie.[Conditional("DEBUG")]
: Ce code atteindra l'IL, cependant les appels à la méthode seront omis à moins que DEBUG ne soit défini lors de la compilation de l'appelant.Personnellement j'utilise les deux en fonction de la situation:
Conditionnel ("DEBUG") Exemple: je l'utilise pour ne pas avoir à revenir en arrière et éditer mon code plus tard pendant la sortie, mais pendant le débogage, je veux être sûr de ne pas avoir fait de fautes de frappe. Cette fonction vérifie que je tape correctement un nom de propriété lorsque j'essaie de l'utiliser dans mon contenu INotifyPropertyChanged.
Vous ne voulez vraiment pas créer une fonction à
#if DEBUG
moins que vous ne souhaitiez boucler chaque appel à cette fonction avec la même chose#if DEBUG
:contre:
#if exemple DEBUG: je l'utilise lorsque j'essaie de configurer différentes liaisons pour la communication WCF.
Dans le premier exemple, le code existe tous, mais est simplement ignoré sauf si DEBUG est activé. Dans le deuxième exemple, la constante ENDPOINT est définie sur "Localhost" ou "BasicHttpBinding" selon que DEBUG est défini ou non.
Mise à jour: je mets à jour cette réponse pour clarifier un point important et délicat. Si vous choisissez d'utiliser le
ConditionalAttribute
, gardez à l'esprit que les appels sont omis lors de la compilation et non lors de l'exécution . C'est:MyLibrary.dll
Lorsque la bibliothèque est compilée en mode de libération (c'est-à-dire sans symbole DEBUG), l'appel à
B()
de l'intérieur estA()
omis pour toujours, même si un appel àA()
est inclus car DEBUG est défini dans l'assembly appelant.la source
Eh bien, il convient de noter qu'ils ne signifient pas du tout la même chose.
Si le symbole DEBUG n'est pas défini, alors dans le premier cas le
SetPrivateValue
lui - même ne sera pas appelé ... alors que dans le second cas il existera, mais tous les appelants qui sont compilés sans le symbole DEBUG verront ces appels omis.Si le code et tous ses appelants sont dans le même assemblage, cette différence est moins importante - mais cela signifie que dans le premier cas, vous devez également avoir
#if DEBUG
autour du code appelant .Personnellement, je recommanderais la deuxième approche - mais vous devez garder la différence entre eux claire dans votre tête.
la source
Je suis sûr que beaucoup seront en désaccord avec moi, mais après avoir passé du temps en tant que gars de la construction à entendre constamment "Mais cela fonctionne sur ma machine!", Je pense que vous ne devriez pratiquement jamais utiliser non plus. Si vous avez vraiment besoin de quelque chose pour les tests et le débogage, trouvez un moyen de séparer cette testabilité du code de production réel.
Résumé des scénarios avec des simulations dans les tests unitaires, faites des versions uniques des choses pour les scénarios uniques que vous souhaitez tester, mais ne placez pas de tests de débogage dans le code des binaires que vous testez et écrivez pour la version de production. Ces tests de débogage masquent simplement les éventuels bogues des développeurs afin qu'ils ne soient trouvés que plus tard dans le processus.
la source
#if debug
d'une construction similaire dans votre code?#if DEBUG
sorte que nous ne spammions pas accidentellement les autres tout en testant un système qui doit transmettre des e-mails dans le cadre du processus. Parfois, ce sont les bons outils pour le travail :)Celui-ci peut également être utile:
la source
Debugger.IsAttached
doit être appelé au moment de l'exécution, même dans les versions.Avec le premier exemple,
SetPrivateValue
n'existera pas dans la build siDEBUG
n'est pas défini, avec le second exemple, les appels àSetPrivateValue
n'existeront pas dans la build siDEBUG
n'est pas défini.Avec le premier exemple, vous devrez également envelopper tous les appels
SetPrivateValue
avec#if DEBUG
.Avec le deuxième exemple, les appels à
SetPrivateValue
seront omis, mais sachez queSetPrivateValue
lui - même sera toujours compilé. Ceci est utile si vous créez une bibliothèque, donc une application référençant votre bibliothèque peut toujours utiliser votre fonction (si la condition est remplie).Si vous souhaitez omettre les appels et économiser l'espace de l'appelé, vous pouvez utiliser une combinaison des deux techniques:
la source
#if DEBUG
aroundConditional("DEBUG")
ne supprime pas les appels à cette fonction, il supprime simplement la fonction de IL tous ensemble, donc vous avez toujours des appels à une fonction qui n'existe pas (erreurs de compilation).Supposons que votre code contienne également une
#else
instruction qui définit une fonction de stub nul, abordant l'un des points de Jon Skeet. Il y a une deuxième distinction importante entre les deux.Supposons que la fonction
#if DEBUG
ouConditional
existe dans une DLL référencée par l'exécutable de votre projet principal. À l'aide de#if
, l'évaluation du conditionnel sera effectuée en fonction des paramètres de compilation de la bibliothèque. En utilisant l'Conditional
attribut, l'évaluation du conditionnel sera effectuée en ce qui concerne les paramètres de compilation de l'invocateur.la source
J'ai une extension SOAP WebService pour enregistrer le trafic réseau à l'aide d'une personnalisation
[TraceExtension]
. Je l'utilise uniquement pour les versions de débogage et j'omet des versions de version . Utilisez le#if DEBUG
pour envelopper l'[TraceExtension]
attribut, le supprimant ainsi des versions Release .la source
Habituellement, vous en auriez besoin dans Program.cs où vous souhaitez décider d'exécuter le débogage sur du code non-débogage et cela principalement dans les services Windows. J'ai donc créé un champ en lecture seule IsDebugMode et défini sa valeur dans le constructeur statique comme indiqué ci-dessous.
la source