[Conditional("DEBUG")]
private void CheckState()
{
string caller = new StackTrace().GetFrame(1).GetMethod().Name;
Trace.WriteLine($"Entering CheckState for Person (called by {caller})");
Debug.Assert(_lastName != null, caller, "Last Name cannot be null");
Debug.Assert(_lastName.Length > 0, caller, "Last Name cannot be blank");
Debug.Assert(_firstName != null, caller, "First Name cannot be null");
Debug.Assert(_firstName.Length > 0, caller, "First Name cannot be blank");
Trace.WriteLine("Exiting CheckState for Person");
}
public string LastName
{
get
{
CheckState(); // DEBUG 時執行驗證,RELEASE 時直接移除呼叫
return _lastName;
}
set
{
CheckState();
_lastName = value;
CheckState();
}
}
| 特性 | ConditionalAttribute | #if / #endif |
|---|---|---|
| 呼叫端處理 | 編譯器移除呼叫指令,零開銷 | 保留空方法呼叫,仍有呼叫開銷 |
| 程式碼結構 | 邏輯集中在方法內,乾淨 | 散落在各處,難以維護 |
| 編譯器支援 | 原生識別,IntelliSense 正常 | 預處理器指令,工具支援較弱 |
| 副作用風險 | 無(呼叫被移除,引數不評估) | 高(引數仍會評估,如 GetDiagnostics()) |
| 適用範圍 | 僅方法 | 任意程式碼區塊 |
public void BadExample()
{
string msg = null;
#if DEBUG
msg = GetDiagnostics(); // 只有 DEBUG 時賦值
#endif
Console.WriteLine(msg); // RELEASE 印出 null → 空行,非預期!
}
條件屬性版本:
[Conditional("DEBUG")]
private void LogDiagnostics(string msg) { Console.WriteLine(msg); }
public void GoodExample()
{
LogDiagnostics(GetDiagnostics()); // RELEASE 時整個呼叫(含引數評估)被移除
}
void 回傳的方法Conditional 的方法不可為 public(建議 private/internal)[Conditional("DEBUG"), Conditional("TRACE")] 任一符合即保留Conditional("DEBUG")#if FEATURE_X#if NETCOREAPP / #if WINDOWS#if 區塊內放置有副作用的運算式