前置處理器指令本質
C# 無獨立前置處理器,#define/#undef 等指令在詞法分析階段由編譯器直接處理。指令以 # 開頭,必須獨佔行 (前可有空白)。
#define:定義條件編譯符號
#define DEBUG
#define TRACE
#define MY_SYMBOL
- 符號無值,只有「定義」與「未定義」兩種狀態
- 類似 C/C++ 巨集定義,但不支援參數、不支援替換文本
- 僅供
#if/#elif 條件判斷使用
#undef:取消符號定義
#define TEMP
#undef TEMP // 取消定義
#undef TEMP // 重複取消:合法,無效果
作用域:整個原始檔
- 從定義行開始,到檔案結束
- 不跨越檔案 (每個 .cs 獨立)
- 不受
namespace/class 區塊限制
關鍵限制:必須在「實際程式碼」之前
// 合法:在 using/namespace/class 之前
#define DEBUG
using System;
namespace App { class Program { } }
// 合法:在 #if 區塊內 (因 #if 非實際程式碼)
#define A
#if A
#define B
#endif
namespace App { #if B class C { } #endif }
// 錯誤:在實際程式碼之後
using System;
#define DEBUG // CS1024: 前置處理器指示詞必須在檔案最前面
「實際程式碼」判定規則
| 屬於實際程式碼 | 不屬於 (可在其前定義符號) |
using 指令 | #define, #undef, #if, #elif, #else, #endif |
namespace 宣告 | #error, #warning, #region, #endregion |
class/struct/interface 等型別宣告 | 註解 (單行/多行) |
| 方法/屬性/欄位等成員宣告 | |
| 陳述式、運算式 | |
專案層級符號定義 (推薦做法)
避免在原始碼硬編碼 #define,改用專案屬性或建置參數:
- Visual Studio:專案屬性 → Build → Conditional compilation symbols
.csproj:<DefineConstants>DEBUG;TRACE</DefineConstants>
dotnet build:-p:DefineConstants="DEBUG;TRACE"
優點:集中管理、CI/CD 可控、不汙染原始碼。
預定義符號
| 符號 | 定義條件 |
DEBUG | 專案屬性 "Define DEBUG constant" 勾選 (預設 Debug 配置) |
TRACE | 專案屬性 "Define TRACE constant" 勾選 (預設兩者皆勾選) |
NETFRAMEWORK | 目標 .NET Framework |
NETCOREAPP | 目標 .NET Core / .NET 5+ |
NETSTANDARD | 目標 .NET Standard |
NET6_0_OR_GREATER | 目標 .NET 6.0+ (版本特定符號) |
總結
#define/#undef 定義條件編譯符號,作用域為整個檔案,必須置於所有實際程式碼之前。現代專案建議使用專案層級 DefineConstants 統一管理,搭配預定義符號 (DEBUG, NET6_0_OR_GREATER 等) 實現跨平台、多配置建置控制。
- 上一篇文章: C# 條件編譯指令詳解:#if、#elif、#else、#endif 巢狀與邏輯運算
- 下一篇文章: C# foreach 迴圈深度解析:語法、集合介面契約、唯讀語意與效能
Copyright ©
程式碼之家 All Rights Reserved