條件編譯指令用於按條件包含或排除源文件中的某些部分。
按照語法的規定,條件編譯指令必須寫成集的形式,集的組成依次為:一個 #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]