Директивы if/then C# для debug vs release

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

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

#define DEBUG 
#define RELEASE

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

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

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

12 ответов


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

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

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

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

Не проверяйте для выпуска


по умолчанию 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();
}

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

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

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


Я не большой поклонник материала #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;
    }
}

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

#define DEBUG  
#define RELEASE 

... это вызовет #if (DEBUG) всегда быть правдой.

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

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

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

bool isDebug = false;
Debug.Assert(isDebug = true); // '=', not '=='

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

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

если DEBUG определяется isDebug установлено значение true (и перешло к Debug.Assert , который ничего не делает в это дело.)


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

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

немного изменен (извращенные?) версия ответа Тода Томсона как статическая функция, а не отдельный класс (я хотел иметь возможность вызывать его в viewbinding 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;
}

пространство имен

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

совет, который может спасти вас много времени - не забывайте, что даже если вы выберете debug в конфигурации сборки (в меню vs2012 / 13 В разделе BUILD => CONFIGURATION MANAGER) - этого недостаточно.

вы должны обратить внимание на публикацию Configuration, например:

enter image description here


поскольку цель этих директив компилятора состоит в том, чтобы сказать компилятору не включать код,отладочный код, бета-код или, возможно, код, который необходим всем вашим конечным пользователям, за исключением, скажем, рекламного отдела, т. е. #Define AdDept вы хотите иметь возможность включать или удалять их в зависимости от ваших потребностей. Без необходимости изменять исходный код, если, например, не AdDept сливается с AdDept. Тогда все, что нужно сделать, это включить директиву #AdDept в параметры компилятора страница свойств существующей версии программы и сделать компиляцию и wa la! код Объединенной программы оживает!.

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

во всяком случае, так я это делаю.


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

Define DEBUG constant in Project Build Properties