2012-03-22 96 views
1

有時我發現預處理程序指令對我的應用程序來說不夠靈活,所以我一直在想是否有可能交換預處理程序的#if功能。if語句中的常量條件

例子:

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

將if語句,其內容由編譯刪除?或者,如果Debug常數的值爲true,編譯器是否會刪除條件檢查並保留其內容?

+3

你試圖看看MSIL – 2012-03-22 22:20:02

+0

下載Linqpad,你可以在2分鐘內驗證自己直。 – BrokenGlass 2012-03-22 22:23:20

+0

對於'const'成員,'if'語句將消失。對於靜態只讀成員,聲明將保留。 – dlev 2012-03-22 22:25:03

回答

11

if語句及其內容是否會被編譯器刪除?或者,如果Debug常量的值爲true,編譯器是否會刪除條件檢查並將內容保留在原位?

是的,是的。但是,這些是實現細節,不是語言的保證。

使用if(false)控制條件編譯的一些有趣的方面:​​

編譯是不是條件可言; if的主體將像其他任何代碼一樣被編譯。如果它包含語法錯誤,則會出現語法錯誤。如果它包含重載解析錯誤,你會得到重載解析錯誤。 「轉到使用」和其他IDE功能繼續工作。

這是從與#if false控制非常不同;由於預處理器而被忽略的文本被視爲註釋。 「轉到使用」不會找到有條件編譯的用法,您不會獲得語法着色等等。但是,代碼可以完全破解,因爲畢竟它基本上只是一個評論。

然而,第一點是輕微的謊言;有一個區別。內部if(false)代碼不檢查明確分配錯誤:

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

因爲畢竟有沒有辦法,X向它是寫在這個節目片段之前必須閱讀!

3

if語句及其內容會被編譯器刪除嗎?

是的,即使您在Debug模式下編譯,if語句也會從結果IL中刪除。

或者,如果Debug常量的值爲true,那麼 編譯器是否會刪除條件檢查並將其內容保留在原位?

是的,即使在調試模式下編譯也會發生。

例如:

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 2012-03-22 22:25:37