Скажем, у меня есть следующий фрагмент кода на C#
static const bool DO_PERFORMANCE_CODE = false;
if (DO_PERFORMANCE_CODE)
{
// performance monitoring code goes here
}
Будет ли этот код удален компилятором? Это тот функционал, который мне нужен. В основном я хочу имитировать условную компиляцию в C#, но мне нужно больше конфигураций, кроме Release и Debug. Если есть лучший способ сделать это, я был бы готов его услышать.





Когда вы встраиваете «отладку», определяется переменная препроцессора DEBUG. Итак, вы можете сделать это:
public void MyFunc()
{
//do release stuff
#if DEBUG
//do performance testing
#endif
//finish release stuff
}
и он будет проигнорирован компилятором при переключении в режим Release.
В качестве альтернативы вы можете определить свою собственную переменную препроцессора, если вы не хотите тестировать в режиме отладки, убедившись, что вы выбрали «#define PERFORMANCE_TESTING», когда хотите протестировать, и закомментировав это, когда вы этого не сделаете.
#define PERFORMANCE_TESTING
public void MyFunc()
{
//do release stuff
#if PERFORMANCE_TESTING
//do performance testing
#endif
//finish release stuff
}
Честно говоря, да. Затем я понял, что если вы сосредоточены на производительности, вы можете провести тестирование в режиме выпуска.
Возможно ли иметь вложенные #ifs? Я бы так предположил, но не уверен.
Да, вы можете вложить несколько директив препроцессора.
И очень сложно очень быстро следовать
Атрибут [Conditional] также удобен, когда код производительности находится в методе.
Вы можете определить свои собственные переменные прекомпилятора.
#define temp
#if temp
// Do something
#endif
вы можете определить свои собственные константы либо в верхней части файла:
#define SUPERDOOPERDEBUG
using System;
....
#if SUPERDOOPERDEBUG
// something
#endif
Кроме того, вы можете настроить разные конфигурации сборки, кроме «выпуска» и «отладки» (см. Меню «Сборка» -> «Конфигурация» или укажите дополнительные символы условной компиляции в меню «Проект» -> «Свойства»)
Ух ты, я опередил тебя на 14 секунд.
Я позову вас в следующий раз, инспектор Гаджет!
Вы можете определить больше символов, кроме DEBUG / RELEASE ... просто посмотрите в свойствах проекта :-), тогда вы можете использовать синтаксис директивы препроцессора для необязательного включения вещей на основе конфигурации проекта
Вы не ограничены DEBUG и RELEASE. Вы можете указать другие константы с помощью #define или в свойствах проекта.
Ха. # 5 с тем же ответом. Извините за беспорядок.
Определение ваших собственных символов, вероятно, будет проще, но мне было любопытно, что сделает компилятор, поэтому я немного поэкспериментировал (используя VS 2008 в режиме выпуска).
С этим:
class Program
{
static void Main(string[] args)
{
bool foo = false;
if (foo)
{
Console.WriteLine("Hello, world?");
}
}
}
Компилятор по-прежнему генерирует код для оператора if:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 16 (0x10)
.maxstack 1
.locals init ([0] bool foo)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: brfalse.s IL_000f
IL_0005: ldstr "Hello, world\?"
IL_000a: call void [mscorlib]System.Console::WriteLine(string)
IL_000f: ret
} // end of method Program::Main
Если вместо этого вы сделаете:
class Program
{
static void Main(string[] args)
{
bool foo = false;
if (false)
{
Console.WriteLine("Hello, world?");
}
}
}
Он не генерирует код для оператора if:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 1 (0x1)
.maxstack 8
IL_0000: ret
} // end of method Program::Main
Также кажется, что пропускается переменная, которой присвоено значение, которое никогда не используется.
Я проверил с помощью ildasm.exe, дизассемблера, поставляемого с Visual Studio.
Я провел несколько тестов с Reflector и Visual Studio 2008 SP1, и вот что я нашел.
Когда я увидел ваш ответ, я подумал, что у вас есть только часть #if DEBUG. Я дам вам положительный отзыв, так как он сказал, что ему нужно больше, чем DEBUG и релиз.