條件編譯指令用於按條件包含或排除源文件中的某些部分。
按照語法的規定,條件編譯指令必須寫成集的形式,集的組成依次為:一個 #if 指令、一個或多個 #elif 指令(或沒有)、一個或多個 #else 指令(或沒有)和一個 #endif 指令。指令之間是源代碼的條件節。每節代碼直接位於它前面的那個指令控制。條件節本身可以包含嵌套的條件編譯指令,前提是這些指令構成完整的指令集。
“pp 條件”最多只能選擇一個它所包含的“條件節”去做通常的詞法處理:
#if 和 #elif 指令的“pp 表達式”直到獲得值 true。如果表達式的結果為 true,則選擇對應指令的“條件節”。[1] [2] 下一頁
false 並且存在 #else 指令,則選擇 #else 指令的“條件節”。選定的“條件節”(若有)按正常的“輸入節”處理:節中包含的源代碼必須符合詞法文法;從節中的源代碼生成標記;節中的預處理指令具有規定的效果。
剩余的“條件節”(若有)按“跳過節”處理:除了預處理指令,節中的源代碼不必一定要符合詞法文法;不從節中的源代碼生成任何詞法標記;節中的預處理指令必須在詞法上正確,但不另外處理。在按“跳過節”處理的“條件節”中,任何嵌套的“條件節”(包含在嵌套的 #if...#endif 和 #region...#endregion 構造中)也按“跳過節”處理。
下面的示例闡釋如何嵌套條件編譯指令:
#define Debug // Debugging on
#undef Trace // Tracing off
class PurchaseTransaction
{
void Commit() {
#if Debug
CheckConsistency();
#if Trace
WriteToLog(this.ToString());
#endif
#endif
CommitHelper();
}
}
除預處理指令外,跳過的源代碼與詞法分析無關。例如,盡管在 #else 節中有未結束的注釋,但下面的示例仍然有效:
#define Debug // Debugging on
class PurchaseTransaction
{
void Commit() {
#if Debug
CheckConsistency();
#else
/* Do something else
#endif
}
}
但請注意,即使是在源代碼的跳過節中,也要求預處理指令在詞法上正確。
當預處理指令出現在多行輸入元素的內部時,不作為預處理指令處理。例如,程序:
class Hello
{
static void Main() {
System.Console.WriteLine(@"hello,
#if Debug
world
#else
Nebraska
#endif
");
}
}
輸出結果為:
hello,
#if Debug
world
#else
Nebraska
#endif
在特殊的情況下,如何處理預處理指令集可能取決於 pp 表達式的計算。示例:
#if X
/*
#else
/* */ class Q { }
#endif
總是產生同樣的標記流 (class Q { }),不管是否定義了 X。如果定義了 X,由於多行注釋的緣故,只處理 #if 和 #endif 指令。如果未定義 X,則這三個指令(#if、#else、#endif)是指令集的組成部分。
上一頁 [1] [2]