web-dev-qa-db-fra.com

Directives C # if / then pour debug vs release

Dans les propriétés de la solution, la configuration est configurée sur "release" pour mon seul et unique projet.

Au début de la routine principale, j'ai ce code qui affiche "Mode = Debug". J'ai aussi ces deux lignes tout en haut:

#define DEBUG 
#define RELEASE

Est-ce que je teste la bonne variable?

#if (DEBUG)
            Console.WriteLine("Mode=Debug"); 
#Elif (RELEASE)
            Console.WriteLine("Mode=Release"); 
#endif

Mon objectif est de définir différentes valeurs par défaut pour les variables en fonction du mode débogage vs version.

384
NealWalters

Supprimez le #define DEBUG de votre code. Définissez les préprocesseurs dans la configuration de construction pour cette construction spécifique (DEBUG/_DEBUG doit déjà être défini dans le VS).

La raison pour laquelle il imprime "Mode = Debug" est à cause de votre #define puis ignore la Elif.

Aussi, la bonne façon de vérifier est:

#if DEBUG
    Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif

Ne pas vérifier pour la libération

649
psychotik

Par défaut, Visual Studio définit DEBUG si le projet est compilé en mode débogage et ne le définit pas s'il est en mode publication. RELEASE n'est pas défini en mode Release par défaut. Utilisez quelque chose comme ceci:

#if DEBUG
  // debug stuff goes here
#else
  // release stuff goes here
#endif

Si vous voulez faire quelque chose uniquement en mode release:

#if !DEBUG
  // release...
#endif

Il est également intéressant de noter que vous pouvez utiliser l'attribut [Conditional("DEBUG")] sur les méthodes qui renvoient void pour les exécuter uniquement si un certain symbole est défini. Le compilateur supprimerait tous les appels à ces méthodes si le symbole n'est pas défini:

[Conditional("DEBUG")]
void PrintLog() {
    Console.WriteLine("Debug info");
}

void Test() {
    PrintLog();
}
273
Mehrdad Afshari

Je préfère vérifier comme ceci contre la recherche de #defines:

if (System.Diagnostics.Debugger.IsAttached)
{
   //...
}
else
{
   //...
}

Avec l'avertissement que vous pouvez bien sûr compiler et déployer quelque chose en mode débogage sans toujours avoir le débogueur attaché.

186
Joel Coehoorn

Je ne suis pas un grand fan des choses #if, en particulier si vous le répartissez tout autour de votre base de code car cela vous posera des problèmes lorsque les générations Debug passent mais que les versions Release échouent si vous ne faites pas attention.

Alors voici ce que je suis venu avec (inspiré par # 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;
    }
}
50
Tod Thomson
_bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='
_

La méthode Debug.Assert a l'attribut conditionnel DEBUG. S'il n'est pas défini, l'appel et l'affectation _isDebug = true_ sont éliminés :

Si le symbole est défini, l'appel est inclus. sinon, l'appel (y compris l'évaluation des paramètres de l'appel) est omis.

Si DEBUG est défini, isDebug est défini sur true (et transmis à _Debug.Assert_, ce qui ne fait rien dans ce cas).

20
AlexD

Si vous essayez d'utiliser la variable définie pour le type de construction, vous devez supprimer les deux lignes ...

#define DEBUG  
#define RELEASE 

... ceci fera que # if (DEBUG) sera toujours vrai.

Il n’existe pas non plus de symbole de compilation conditionnelle par défaut pour RELEASE. Si vous voulez en définir un, allez dans les propriétés du projet, cliquez sur l'onglet Build, puis ajoutez RELEASE à la zone de texte Symboles de compilation conditionnelle sous Général rubrique.

L'autre option serait de faire cela ...

#if DEBUG
    Console.WriteLine("Debug");
#else
    Console.WriteLine("Release");
#endif
19
Matthew Whited

Supprimer vos définit en haut

#if DEBUG
        Console.WriteLine("Mode=Debug"); 
#else
        Console.WriteLine("Mode=Release"); 
#endif
7
McAden

Version légèrement modifiée (bastardisée?) De la réponse par Tod Thomson sous forme de fonction statique plutôt que de classe séparée (je voulais pouvoir l'appeler dans une liaison de vue WebForm à partir d'une classe de viewutils que j'avais déjà incluse).

public static bool isDebugging() {
    bool debugging = false;

    WellAreWe(ref debugging);

    return debugging;
}

[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
    debugging = true;
}
7
LocalPCGuy

Assurez-vous de définir la constante DEBUG dans les propriétés de construction du projet. Cela activera le #if DEBUG. Je ne vois pas de constante RELEASE prédéfinie, ce qui pourrait impliquer que tout ce qui n'est pas dans un bloc DEBUG est en mode RELEASE.

Define DEBUG constant in Project Build Properties

4
gridtrak

NameSpace

using System.Resources;
using System.Diagnostics;

Méthode

   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;
    }
4
Ehsan Enaloo

Un conseil qui peut vous faire gagner beaucoup de temps - n’oubliez pas que même si vous choisissez debug dans la configuration de construction (dans le menu vs2012/13, c’est sous BUILD => CONFIGURATION MANAGER) - c’est insuffisant.

Vous devez faire attention à PUBLISH Configuration, en tant que tel:

enter image description here

3
ilans

J'ai commencé à penser à un meilleur moyen. Il m'est apparu que #si les blocs sont effectivement des commentaires dans d'autres configurations (en supposant que DEBUG ou RELEASE; mais vrai avec n'importe quel symbole)

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");
        }
0
user11773533

Dans la mesure où ces directives COMPILER ont pour but d'indiquer au compilateur de ne PAS inclure de code, de code de débogage, de code bêta ou peut-être de code nécessaire à tous vos utilisateurs finaux, à l'exception du service publicité, par exemple #Define AdDept que vous souhaitez. pouvoir les inclure ou les supprimer en fonction de vos besoins. Sans avoir à changer votre code source si, par exemple, un non-AdDept est fusionné dans AdDept. Ensuite, tout ce qui reste à faire est d’inclure la directive #AdDept dans la page de propriétés des options du compilateur d’une version existante du programme et de compiler et wa la! le code du programme fusionné prend vie!.

Vous pouvez également utiliser un déclaratif pour un nouveau processus qui n'est pas prêt pour le prime time ou qui ne peut pas être actif dans le code tant qu'il n'est pas temps de le publier.

Quoi qu'il en soit, c'est comme ça que je le fais.

0
mrMagik3805

Supprimez les définitions et vérifiez si le conditionnel est en mode débogage. Vous n'avez pas besoin de vérifier si la directive est en mode de libération.

Quelque chose comme ça:

#if DEBUG
     Console.WriteLine("Mode=Debug"); 
#else
    Console.WriteLine("Mode=Release"); 
#endif
0
Anderson Ribeiro