488 votes

#if DEBUG vs Conditional("DEBUG")

Quel est le meilleur à utiliser et pourquoi, sur un projet d’envergure :

ou

635voto

m-y Points 12871

Cela dépend vraiment de ce que vous allez pour:

  • #if DEBUG: Le code ici n'atteint même pas le IL sur version.
  • [Conditional("DEBUG")]: Ce code permettra d'atteindre l'IL, cependant que les appels à la méthode ne va pas s'exécuter, sauf si le DÉBOGAGE est activé.

Personnellement, j'utilise les deux, selon la situation:

Conditionnel("DEBUG") Exemple: - je utiliser cela pour que je n'ai pas à revenir en arrière et modifier mon code plus tard au cours de la libération, mais au cours de débogage, je veux être sûr que je n'ai pas fait de fautes de frappe. Cette fonction vérifie que je tape un nom de propriété correctement lorsque vous essayez de l'utiliser dans mon INotifyPropertyChanged choses.

    [Conditional("DEBUG")]
    [DebuggerStepThrough]
    protected void VerifyPropertyName(String propertyName)
    {
        if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            Debug.Fail(String.Format("Invalid property name. Type: {0}, Name: {1}", GetType(), propertyName));
    }

Vous ne voulez vraiment pas à créer une fonction à l'aide d' #if DEBUG sauf si vous êtes prêt à envelopper chaque appel à cette fonction avec le même #if DEBUG:

#if DEBUG
    public void DoSomething() { }
#endif

public void Foo()
{
    DoSomething(); //This will have a compilation error if you're not in DEBUG.
}


#if DEBUG
    public void DoSomething() { }
#endif

    public void Foo()
    {
#if DEBUG
        DoSomething(); //This works, but looks FUGLY
#endif
    }


[Conditional("DEBUG")]
public void DoSomething() { }

public void Foo()
{
    DoSomething(); //Code compiles and is cleaner, DoSomething always
                   //exists, however this is only called during DEBUG.
}

#if DEBUG exemple: je l'utiliser lorsque vous essayez de configurer différentes liaisons pour WCF communication.

#if DEBUG
        public const String ENDPOINT = "Localhost";
#else
        public const String ENDPOINT = "BasicHttpBinding";
#endif

Dans le premier exemple, le code existe, mais est simplement ignorée, sauf si le DÉBOGAGE est activé. Dans le deuxième exemple, la const point de TERMINAISON est "Localhost" ou "BasicHttpBinding" selon si le DÉBOGAGE est activée ou non.


Mise à jour: Parce que cette réponse est la plus haute voté réponse à la question, je suis la mise à jour de cette réponse pour ajouter quelque chose de très important pour elle. Si vous choisissez d'utiliser l' ConditionalAttribute, gardez à l'esprit que les appels sont omis lors de la compilation, et non d'exécution. C'est:

MyLibrary.dll

[Conditional("DEBUG")]
public void A()
{
    Console.WriteLine("A");
    B();
}

[Conditional("DEBUG")]
public void B()
{
    Console.WriteLine("B");
}

Lorsque la bibliothèque est compilée contre la libération de mode (c'est à dire pas de symboles de DÉBOGAGE), il sera toujours avoir à l'appel d' B() de dans les A() omis, même si la consommation de l'assemblée est compilé à l'encontre de débogage.

69voto

Jon Skeet Points 692016

Ainsi, il est intéressant de noter qu'ils ne signifient pas la même chose.

Si les symboles de DÉBOGAGE n'est pas défini, dans le premier cas, l' SetPrivateValue lui-même ne sera pas appelé... alors que dans le second cas, il va exister, mais tout les appelants qui sont compilées sans les symboles de DÉBOGAGE des appels omis.

Si le code et l'ensemble de ses interlocuteurs sont dans la même assemblée, cette différence est moins important, mais elle signifie que dans le premier cas, vous avez également besoin d'avoir #if DEBUG autour de l' appel de code.

Personnellement je conseillerais de la deuxième approche - mais vous avez besoin de garder la différence entre eux clair dans votre tête.

44voto

Jimmy Hoffa Points 3651

Je suis sûr que beaucoup ne seront pas d'accord avec moi, mais après avoir passé du temps comme une construction guy constamment entendre ", Mais il fonctionne sur ma machine!", Je prends le point de vue que vous devez joli beaucoup jamais utiliser. Si vous avez vraiment besoin de quelque chose pour les tests et le débogage, trouver un moyen de faire que la testabilité séparé de la production réelle de code.

Résumé les scénarios avec les moqueries dans les tests unitaires, faire un hors versions de choses pour l'un au large de scénarios que vous souhaitez tester, mais ne mettez pas de tests de débogage dans le code pour les fichiers binaires qui vous tester et d'écrire pour le lancement de la production. Ces tests de débogage juste masquer les éventuels bugs de développeurs afin qu'ils ne sont pas disponibles jusqu'à ce que plus tard dans le processus.

10voto

P Daddy Points 14228

Dans le premier exemple, SetPrivateValue n'existera pas dans le build si DEBUG n'est pas défini, avec le deuxième exemple, les appels d' SetPrivateValue n'existera pas dans le build si DEBUG n'est pas défini.

Dans le premier exemple, vous aurez pour envelopper tous les appels à des SetPrivateValue avec #if DEBUG .

Avec le deuxième exemple, les appels à l' SetPrivateValue sera omis, mais sachez qu' SetPrivateValue lui-même sera toujours compilé. Ceci est utile si vous êtes la construction d'une bibliothèque, donc une application référencement de votre bibliothèque pouvez toujours utiliser votre fonction (si la condition est remplie).

Si vous souhaitez omettre les appels et d'économiser de l'espace de l'appelant, vous pouvez utiliser une combinaison des deux techniques:

[System.Diagnostics.Conditional("DEBUG")]
public void SetPrivateValue(int value){
    #if DEBUG
    // method body here
    #endif
}

5voto

Kennet Belenky Points 2026

Nous allons présume que votre code a également eu un #else déclaration qui définit une valeur null talon de la fonction, s'adressant à l'un de Jon Skeet points. Il y a une deuxième distinction importante entre les deux.

Supposons que l' #if DEBUG ou Conditional fonction existe dans une DLL qui est référencé par votre projet principal de l'exécutable. À l'aide de l' #if, l'évaluation de la condition, sera effectué à la bibliothèque des paramètres de compilation. À l'aide de l' Conditional d'attribut, l'évaluation de la condition sera réalisée à propos de la compilation des paramètres de l'invocateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X