2012-03-22 2 views
1

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

Пример:

const bool Debug = false; 
if (Debug) 
{ 
    ... 
} 

Будет ли заявление и его содержание будут удалены компилятором? В качестве альтернативы, если значение константы Debug равно true, компилятор удалит проверку состояния и сохранит содержимое на месте?

+3

Вы пытались просмотреть msil –

+0

Загрузите Linqpad, и вы сможете проверить себя через 2 минуты. – BrokenGlass

+0

Для членов 'const' инструкция' if' исчезнет. Для членов 'static readonly' оператор останется. – dlev

ответ

11

Будет ли оператор if и его содержимое удалено компилятором? В качестве альтернативы, если значение константы Debug равно true, компилятор удалит проверку состояния и сохранит содержимое на месте?

Да, и да. Однако это детали реализации, а не гарантии языка.

Некоторых интересных аспектов использования if(false) для управления условной компиляции:

сборника не является условным вообще; тело if будет скомпилировано точно так же, как и любой другой код. Если он содержит синтаксические ошибки, вы получите синтаксические ошибки. Если он содержит ошибки разрешения перегрузки, вы получите ошибки разрешения перегрузки. «Перейти к использованию», и другие функции IDE продолжают работать.

Это очень отличается от управления с помощью #if false; текст, который опущен из-за препроцессора, рассматривается как комментарии. «Перейти к использованию» не найдет использование, которое условно скомпилировано, вы не получите синтаксическую раскраску и т. Д. Тем не менее, код может быть полностью нарушен, потому что, в конце концов, это просто комментарий.

Однако первый момент - легкая ложь; есть одно отличие. Код внутри if(false) не проверяется на определенные ошибки присваивания:

int x; 
if (false) 
    Console.WriteLine(x); // no error! 

Потому что в конце концов, нет никакого способа, что х будет прочитать до того, как написано в этом фрагменте программы!

3

Будет ли исключаться оператор if и его содержимое компилятором?

Да, оператор if будет удален из полученного ИИ, даже если вы скомпилируете его в режиме отладки.

В качестве альтернативы, если значение а константа Debug верно, будет компилятора удалить проверку состояния и сохранить содержимое на месте?

Да, и это произойдет даже в случае компиляции в режиме отладки.

Например:

static void Main() 
{ 
    const bool Debug = false; 
    if (Debug) 
    { 
     Console.WriteLine("ok"); 
    } 
} 

приводит к следующему IL:

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    .maxstack 8 
    L_0000: ret 
} 

Как вы можете видеть все тело метода удаляется из IL

и:

static void Main() 
{ 
    const bool Debug = true; 
    if (Debug) 
    { 
     Console.WriteLine("ok"); 
    } 
} 

результаты в:

.method private hidebysig static void Main() cil managed 
{ 
    .entrypoint 
    .maxstack 8 
    L_0000: ldstr "ok" 
    L_0005: call void [mscorlib]System.Console::WriteLine(string) 
    L_000a: ret 
} 

Здесь Console.WriteLine всегда выполняется без выполнения каких-либо if.

+0

Это верно, что также можно увидеть, пытаясь перетащить желтую стрелку выполнения в статически мертвую, если ветвь. Он не будет работать (что может быть проблемой отладки). – usr