首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 條件編譯與 XML 文件註解:構建多版本、可維護的專業代碼庫

     編輯:關於C語言

條件編譯:同一代碼庫,多種建置變體

條件編譯允許在編譯時決定包含或排除代碼區塊,常見用途:

  • Debug / Release 差異(日誌、斷言、效能計數器)
  • 功能旗標(Demo 版、完整版、企業版)
  • 平台特定代碼(Windows / Linux / 行動裝置)
  • 授權驗證、試用期限制

兩種實作方式

1. 預處理器指示詞

C# 無獨立預處理器,編譯器內建模擬,支援:

// 定義符號(檔案層級,必須在最前面,using 之前)
#define DEBUG
#define TRIAL_VERSION

// 取消定義
#undef TRIAL_VERSION

// 條件包含代碼
#if DEBUG
    Console.WriteLine("除錯模式:啟用詳細日誌");
#elif RELEASE && !TRIAL_VERSION
    Console.WriteLine("正式版:完整功能");
#else
    Console.WriteLine("試用版:功能受限");
#endif

// 邏輯運算子:&& (AND)、|| (OR)、! (NOT)
#if (DEBUG || TESTING) && !DISABLE_LOGGING
    Log.Verbose("進入關鍵路徑");
#endif

// 編譯時警告/錯誤
#if DEMO_VERSION && DEBUG
    #warning 正在建置 Demo 版除錯建置,請確認配置
#endif

#if DEBUG && RELEASE
    #error 無法同時定義 DEBUG 與 RELEASE
#endif

編譯器命令列定義符號

csc /define:DEBUG;TRACE;MY_FEATURE Program.cs
csc /define:RELEASE /define:ENTERPRISE_EDITION Program.cs

Visual Studio 專案屬性設定

  • 專案右鍵 → 屬性 > 建置
  • 條件編譯符號:輸入 `DEBUG;TRACE;MY_FEATURE`(分號分隔)
  • 可針對不同 Configuration (Debug/Release) 設定不同符號

2. ConditionalAttribute:方法層級條件編譯

更優雅、型別安全的方式,標記方法僅在符號定義時編入:

using System.Diagnostics;

public class Logger
{
    // 僅當 DEBUG 定義時,此方法與其呼叫才會被編譯
    [Conditional("DEBUG")]
    public static void Debug(string message)
    {
        Console.WriteLine($"[DEBUG] {DateTime.Now:HH:mm:ss} {message}");
    }

    [Conditional("TRACE")]
    public static void Trace(string format, params object[] args)
    {
        Console.WriteLine($"[TRACE] {string.Format(format, args)}");
    }

    // 多重條件:任一符號定義即編入(邏輯 OR)
    [Conditional("DEBUG"), Conditional("FORCE_LOG")]
    public static void ForceLog(string message) { ... }
}

// 呼叫端
Logger.Debug("這行在 Release 版會完全消失,零開銷");
Logger.Trace("用戶 {0} 登入", userName);

ConditionalAttribute 限制

  • 方法必須回傳 void
  • 不能是介面實作、override、虛擬方法
  • 屬性存取子、建構子、運算子不適用
  • 呼叫端也會被條件編譯(如同宏展開)

XML 文件註解:代碼即文件

編譯器可產出 XML 文件檔,支援 IntelliSense、API 文件生成器(DocFX、Sandcastle)、IDE 工具提示。

啟用 XML 文件產出

  • 專案屬性 → 建置 > 輸出 → 勾選 XML 文件檔(如 `bin\Debug\MyLib.xml`)
  • 命令列:csc /doc:MyLib.xml Program.cs

常用標籤完整指南

標籤用途範例
<summary>類別/方法/屬性簡短描述<summary>計算兩數總和</summary>
<remarks>補充說明、用法範例<remarks>此方法執行緒安全</remarks>
<param name="p">參數描述<param name="a">第一個加數</param>
<returns>傳回值描述<returns>兩數之和</returns>
<exception cref="T">可能拋出的例外<exception cref="ArgumentNullException">參數為 null</exception>
<example>代碼範例見下方完整範例
<code>程式碼片段<code>var sum = Add(1,2);</code>
<see cref="T">參考其他型別/成員<see cref="Math.Max"/>
<seealso cref="T">參考相關主題<seealso cref="System.Math"/>
<para>段落分隔用於 remarks/example 內部
<list type="bullet/number/table">列表/表格見下方完整範例
<paramref name="p"/>參考參數名(斜體顯示)參數 <paramref name="a"/> 不可為負
<typeparam name="T">泛型型別參數<typeparam name="T">元素型別</typeparam>

完整範例:WebRequest 類別文件化

using System;
using System.Net;
using System.IO;
using System.Text;

/// 
/// 從 Web 伺服器擷取網頁內容的工具類別。
/// 
/// 
/// 支援同步與非同步操作。
/// 內部使用  與  處理網路傳輸。
/// 
/// 建構函式: 或 
/// 設定 URL: 屬性
/// 取得內容:
/// 
/// 
/// 
/// 
/// var client = new RequestWebPage("https://example.com");
/// if (client.GetContent(out string html))
/// {
///     Console.WriteLine(html.Substring(0, 200));
/// }
/// 
/// 
/// 
public class RequestWebPage
{
    private const int BufferSize = 4096;
    private string _url;

    /// 
    /// 無參數建構函式,稍後需設定  屬性。
    /// 
    public RequestWebPage() { }

    /// 
    /// 指定目標 URL 的建構函式。
    /// 
    /// 完整網址(含 https:// 或 https://)
    ///  為空白
    public RequestWebPage(string url)
    {
        Url = url ?? throw new ArgumentNullException(nameof(url));
    }

    /// 
    /// 目標網頁 URL。
    /// 
    /// 完整網址字串
    /// 設定為空白字串
    public string Url
    {
        get => _url;
        set => _url = value ?? throw new ArgumentNullException(nameof(value));
    }

    /// 
    /// 擷取網頁內容。
    /// 
    /// 輸出參數,接收網頁 HTML 字串
    /// 成功傳回 true;URL 未設定或網路錯誤傳回 false
    /// URL 未設定
    /// 網路連線失敗
    public bool GetContent(out string content)
    {
        content = string.Empty;
        if (string.IsNullOrEmpty(_url))
            throw new ArgumentException("URL 必須指定", nameof(Url));

        try
        {
            var request = WebRequest.Create(_url);
            using var response = request.GetResponse();
            using var stream = response.GetResponseStream();
            using var reader = new StreamReader(stream, Encoding.UTF8);
            content = reader.ReadToEnd();
            return true;
        }
        catch (WebException)
        {
            return false;
        }
    }
}

整合建置流程



  DEBUG;TRACE
  bin\Debug\$(AssemblyName).xml



  RELEASE;TRACE
  bin\Release\$(AssemblyName).xml




  

總結

條件編譯讓單一代碼庫支援多種建置變體,#if 適合區塊控制,[Conditional] 適合方法層級且零呼叫開銷。XML 文件註解則將文件內嵌代碼,配合工具鏈實現「文件即代碼,代碼即文件」。兩者結合,構建專業、可維護、多版本共存的企業級 .NET 代碼庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved