C#, если/затем директивы для отладки против освобождения


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

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

#define DEBUG 
#define RELEASE

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

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

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

12 349

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, если проект компилируется в режиме отладки, и не определяет его, если он находится в режиме выпуска. Выпуск не определен в режиме выпуска по умолчанию. Использовать что-то вроде этого:

#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();
}

Я предпочитаю проверять его так, а не искать #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

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