C # if / then директивы для отладки и выпуска - PullRequest
384 голосов
/ 20 января 2010

В свойствах решения у меня есть Конфигурация, установленная на "выпуск" для моего единственного проекта.

В начале основной процедуры у меня есть этот код, и он показывает «Mode = Debug». У меня также есть эти две строки в самом верху:

#define DEBUG 
#define RELEASE

Тестирую ли я правильную переменную?

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

Моя цель - установить разные значения по умолчанию для переменных в зависимости от режима отладки и выпуска.

Ответы [ 12 ]

643 голосов
/ 20 января 2010

Удалите #define DEBUG из вашего кода. Установите препроцессоры в конфигурации сборки для этой конкретной сборки (DEBUG / _DEBUG уже должны быть определены в VS).

Причина, по которой он печатает "Mode = Debug", заключается в том, что вы #define, а затем пропускаете elif.

Кроме того, правильный способ проверки:

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

Не проверять на РЕЛИЗ

270 голосов
/ 20 января 2010

По умолчанию Visual Studio определяет DEBUG, если проект компилируется в режиме отладки, и не определяет его, если он находится в режиме выпуска. RELEASE не определяется в режиме Release по умолчанию. Используйте что-то вроде этого:

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

Если вы хотите сделать что-то только в режиме релиза:

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

Также стоит указать, что вы можете использовать атрибут [Conditional("DEBUG")] в методах, которые возвращают void, чтобы они выполнялись только в том случае, если определен определенный символ. Компилятор удалит все вызовы этих методов, если символ не определен:

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

void Test() {
    PrintLog();
}
183 голосов
/ 20 января 2010

Я предпочитаю проверять это так, как ищу #defines:

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

С оговоркой, что вы, конечно, можете скомпилировать и развернуть что-либо в режиме отладки, но при этом отладчик не будет подключен.

49 голосов
/ 08 марта 2013

Я не большой поклонник #if, особенно если вы распространяете его по всей кодовой базе, так как это создаст вам проблемы в тех случаях, когда отладочные сборки проходят, но выпуски релизов завершаются неудачно, если вы не будете осторожны.

Итак, вот что я придумал (вдохновлено # ifdef в 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;
    }
}
20 голосов
/ 29 января 2014
bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

Метод Debug.Assert имеет условный атрибут DEBUG. Если он не определен, вызов и назначение isDebug = true исключены :

Если символ определен, вызов включен; в противном случае вызов (включая оценку параметров вызова) опускается.

Если определено DEBUG, isDebug устанавливается в true (и передается в Debug.Assert, что в этом случае ничего не делает).

18 голосов
/ 20 января 2010

Если вы пытаетесь использовать переменную, определенную для типа сборки, вы должны удалить две строки ...

#define DEBUG  
#define RELEASE 

... это приведет к тому, что # if (DEBUG) всегда будет истинным.

Также нет символа условной компиляции по умолчанию для RELEASE . Если вы хотите определить один переход к свойствам проекта, щелкните вкладку Build и добавьте RELEASE в текстовое поле Условные символы компиляции *1013* под заголовком General .

Другой вариант - сделать это ...

#if DEBUG
    Console.WriteLine("Debug");
#else
    Console.WriteLine("Release");
#endif
7 голосов
/ 23 апреля 2014

Слегка измененная (убитая?) Версия ответа Тода Томсона как статическая функция, а не отдельный класс (я хотел иметь возможность вызывать ее в привязке представления WebForm из класса viewutils, который я уже включил).

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

    WellAreWe(ref debugging);

    return debugging;
}

[Conditional("DEBUG")]
private static void WellAreWe(ref bool debugging)
{
    debugging = true;
}
7 голосов
/ 20 января 2010

Удалить ваши определения в верхней части

#if DEBUG
        Console.WriteLine("Mode=Debug"); 
#else
        Console.WriteLine("Mode=Release"); 
#endif
4 голосов
/ 11 июля 2018

Обязательно укажите константу DEBUG в свойствах сборки проекта. Это включит #if DEBUG. Я не вижу заранее определенной константы RELEASE, поэтому это может означать, что все, что не находится в блоке DEBUG, находится в режиме RELEASE.

Define DEBUG constant in Project Build Properties

4 голосов
/ 07 мая 2012

NameSpace

using System.Resources;
using System.Diagnostics;

Метод

   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;
    }
...