| 運算子 | 語意 | 範例 |
&& | 邏輯且 | #if DEBUG && VERBOSE |
|| | 邏輯或 | #if DEBUG || TRACE |
! | 邏輯非 | #if !RELEASE |
==, != | 符號存在性比較 | #if DEBUG == true (等同 #if DEBUG) |
優先序:! > && > ||。可用括號分組 (C# 允許)。
完整範例:多重條件分支
#define A
#define B
#undef C
class Demo
{
#if C
void F() { } // 不編譯
#elif A && B
void I() { } // 編譯此方法
#else
void G() { } // 不編譯
#endif
}
// 等效於:
class Demo { void I() { } }
巢狀條件編譯
#define DEBUG
#undef TRACE
class Transaction
{
void Commit()
{
#if DEBUG
CheckConsistency();
#if TRACE
WriteToLog(this.ToString());
#endif
#endif
CommitHelper();
}
}
- 巢狀層級無限制
- 每個
#if 必須配對 #endif
- 內層符號可依賴外層條件
常見錯誤與誤區
1. 指令出現在程式碼中間
// 錯誤:前置處理器指令不在行首 (前有非空白字元)
int x = 1; #if DEBUG x = 2; #endif
// 正確:獨立行
int x = 1;
#if DEBUG
x = 2;
#endif
2. 字串字面值中無效
// 錯誤:前置處理器不解析字串內容
Console.WriteLine(@"Hello #if DEBUG World #else Everyone #endif");
// 輸出原文,非條件編譯結果
3. 符號定義位置
// 錯誤:#define 在 using 之後
using System;
#define MY_SYMBOL // CS1024
// 正確:在檔案最頂端
#define MY_SYMBOL
using System;
條件編譯 vs 條件屬性
// #if 方式:整個方法保留/移除
#if DEBUG
public void Trace(string msg) { Console.WriteLine(msg); }
#endif
// [Conditional] 方式:方法保留,呼叫點移除
[Conditional("DEBUG")]
public void Trace(string msg) { Console.WriteLine(msg); }
// 差異:[Conditional] 連同參數評估一併移除
Trace(ExpensiveCompute()); // DEBUG 未定義時,ExpensiveComplete() 不執行
總結
#if/#elif/#else/#endif 是 C# 條件編譯的核心,支援邏輯運算與巢狀。關鍵限制:必須在行首、不處理字串內容、符號定義在實際程式碼前。方法層級條件編譯優先使用 [Conditional] 獲得參數評估控制優勢。
- 上一篇文章: C# #error 與 #warning 指令實戰:建置時期強制規範與提醒
- 下一篇文章: C# 前置處理器指令:#define、#undef 符號定義與作用域規則
Copyright ©
程式碼之家 All Rights Reserved