有時我發現預處理程序指令對我的應用程序來說不夠靈活,所以我一直在想是否有可能交換預處理程序的#if
功能。if語句中的常量條件
例子:
const bool Debug = false;
if (Debug)
{
...
}
將if語句,其內容由編譯刪除?或者,如果Debug
常數的值爲true
,編譯器是否會刪除條件檢查並保留其內容?
有時我發現預處理程序指令對我的應用程序來說不夠靈活,所以我一直在想是否有可能交換預處理程序的#if
功能。if語句中的常量條件
例子:
const bool Debug = false;
if (Debug)
{
...
}
將if語句,其內容由編譯刪除?或者,如果Debug
常數的值爲true
,編譯器是否會刪除條件檢查並保留其內容?
if語句及其內容是否會被編譯器刪除?或者,如果Debug常量的值爲true,編譯器是否會刪除條件檢查並將內容保留在原位?
是的,是的。但是,這些是實現細節,不是語言的保證。
使用if(false)
控制條件編譯的一些有趣的方面:
的編譯是不是條件可言; if
的主體將像其他任何代碼一樣被編譯。如果它包含語法錯誤,則會出現語法錯誤。如果它包含重載解析錯誤,你會得到重載解析錯誤。 「轉到使用」和其他IDE功能繼續工作。
這是從與#if false
控制非常不同;由於預處理器而被忽略的文本被視爲註釋。 「轉到使用」不會找到有條件編譯的用法,您不會獲得語法着色等等。但是,代碼可以完全破解,因爲畢竟它基本上只是一個評論。
然而,第一點是輕微的謊言;有一個區別。內部if(false)
代碼不檢查明確分配錯誤:
int x;
if (false)
Console.WriteLine(x); // no error!
因爲畢竟有沒有辦法,X向它是寫在這個節目片段之前必須閱讀!
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
始終執行。
這是真的,這也可以通過試圖將黃色執行箭頭拖到靜態死亡分支中來看出。它不會工作(這可能是一個調試問題)。 – usr 2012-03-22 22:25:37
你試圖看看MSIL – 2012-03-22 22:20:02
下載Linqpad,你可以在2分鐘內驗證自己直。 – BrokenGlass 2012-03-22 22:23:20
對於'const'成員,'if'語句將消失。對於靜態只讀成員,聲明將保留。 – dlev 2012-03-22 22:25:03