1. 程式人生 > >使用.NET中的XML註釋(一) -- XML註釋標籤講解

使用.NET中的XML註釋(一) -- XML註釋標籤講解

一.摘要

    .Net允許開發人員在原始碼中插入XML註釋,這在多人協作開發的時候顯得特別有用。 C#解析器可以把程式碼檔案中的這些XML標記提取出來,並作進一步的處理為外部文件。 這篇文章將展示如何使用這些XML註釋。 在專案開發中,很多人並不樂意寫繁雜的文件。但是,開發組長希望程式碼註釋儘可能詳細;專案規劃人員希望程式碼設計文件儘可能詳盡;測試、檢查人員希望功能說明書儘可能詳細等等。如果這些文件都被要求寫的話,保持它們同步比進行一個戰役還痛苦。

為何不把這些資訊儲存在一個地方呢??最明顯想到的地方就是程式碼的註釋中;但是你很難通覽程式,並且有些需要這些文件的人並不懂編碼。最好的辦法是通過使用XML註釋來解決這些問題。程式碼註釋、使用者手冊、開發人員手冊、測試計劃等很多文件可以很方便的從XML註釋中獲得。本文講解.Net中經常使用的XML註釋.主要使用C#語言j,.Net平臺支援的其他語言使用的XML註釋格式基本相同.並且在本系列文章的下一講中講解如何使用工具將XML註釋內容轉化為幫助文件.

二.XML註釋概述

所有的XML註釋都在三個向前的斜線之後(///)。兩條斜線表示是一個註釋,編譯器將忽略後面的內容。三條斜線告訴編譯器,後面是XML註釋,需要適當地處理。

當開發人員輸入三個向前的斜線後,Microsoft Visual Studio .NET IDE 自動檢查它是否在類或者類成員的定義的前面。如果是的話,Visual Studio .NET IDE 將自動插入註釋標記,開發人員只需要增加些額外的標記和值。下面就是在成員函式前增加三個斜線,自動增加的註釋比如:

        
	/// <summary>
        /// 得到指定酒店的酒店資訊
        /// </summary>
/// <param name="hotelId">酒店Id</param> /// <param name="languageCode">語言碼.中文為zh-cn</param> /// <returns>酒店資訊物件</returns> [OperationContract] OutHotelInfo GetHotelInfoByHotelId(string loginName, string loginPassword, string hotelId, string
languageCode);

這裡嵌入的summary,param,returns標記僅僅是Visual Studio能夠識別的一部分標記,然而在智慧感知IntelliSense中,並沒有把c#規範中所有的標記列出來,遺失的部分只能用手工插入。 這些手工標記是非常有用的,如果恰當地設定他們,對匯出成外部說明檔案將非常有幫助。

三.將註釋生成XML檔案

在程式碼中新增的註釋資訊, 可以單獨提取出來, 生成XML檔案. 在製作最後的幫助檔案的時候會使用到這些註釋XML檔案.

預設情況下是不生成註釋XML檔案的.每個專案可以生成一個XML檔案,需要我們在專案屬性中進行設定:

如上圖所示,在專案的"屬性頁"->"生成"中, 勾選"XML文件檔案"複選框,即可在編譯時生成註釋XML檔案.生成路徑預設是和dll檔案在同一個資料夾下,也可以自行修改.注意此處填寫的是相對路徑.

四.常見註釋標籤列表

註釋的使用很簡單,但是我們使用到的註釋很少.這是因為大部分專案中註釋的作用僅僅是給程式設計師自己看.如果想要生成類似MSDN這樣的文件,我們需要了解更多的註釋標籤.下面是我整理的常用的註釋標籤:

標籤名稱

說明

語法

引數

<summary>

<summary> 標記應當用於描述型別或型別成員。使用 <remarks> 新增針對某個型別說明的補充資訊。

<summary> 標記的文字是唯一有關IntelliSense 中的型別的資訊源,它也顯示在 物件瀏覽器 中。

<summary>

Description

</summary>

description:物件的摘要。

<remarks>

使用 <remarks>標記新增有關型別的資訊,以此補充用 <summary> 指定的資訊。此資訊顯示在物件瀏覽器中。

<remarks>

Description

</remarks>

description:成員的說明。

<param>

<param> 標記應當用於方法宣告的註釋中,以描述方法的一個引數。

有關 <param> 標記的文字將顯示在IntelliSense、物件瀏覽器和程式碼註釋 Web 報表中。

<paramname='name'>

description

</param>

name:方法引數名。將此名稱用雙引號括起來 (" ")

description:引數說明。

<returns>

<returns> 標記應當用於方法宣告的註釋,以描述返回值。

<returns>

Description

</returns>

description:返回值的說明。

<value>

<value> 標記使您得以描述屬性所代表的值。請注意,當在 Visual Studio .NET 開發環境中通過程式碼嚮導新增屬性時,它將會為新屬性新增<summary> 標記。然後,應該手動新增 <value> 標記以描述該屬性所表示的值。

<value>

property-description

</value>

property-description:屬性的說明

<example>

使用 <example> 標記可以指定使用方法或其他庫成員的示例。這通常涉及使用 <code> 標記。

<example>

Description

</example>

description: 程式碼示例的說明。

<c>

<c> 標記為您提供了一種將說明中的文字標記為程式碼的方法。使用<code> 將多行指示為程式碼。

<c>

Text

</c>

text :希望將其指示為程式碼的文字。

<code>

使用 <code> 標記將多行指示為程式碼。使用<c>指示應將說明中的文字標記為程式碼。

<code>

Content

</code>

content:希望將其標記為程式碼的文字。

<exception>

<exception> 標記使您可以指定哪些異常可被引發。此標記可用在方法、屬性、事件和索引器的定義中。

<exception

cref="member">

Description

</exception>

cref:

對可從當前編譯環境中獲取的異常的引用。編譯器檢查到給定異常存在後,將 member 轉換為輸出 XML 中的規範化元素名。必須將 member 括在雙引號 (" ")中。

有關如何建立對泛型型別的cref 引用的更多資訊,請參見<see>

description:異常的說明。

<see>

<seealso>

<see> 標記使您得以從文字內指定連結。使用 <seealso> 指示文字應該放在“另請參見”節中。

<seecref="member"/>

cref:

對可以通過當前編譯環境進行呼叫的成員或欄位的引用。編譯器檢查給定的程式碼元素是否存在,並將 member 傳遞給輸出 XML中的元素名稱。應將 member 放在雙引號 (" ") 中。

<para>

<para> 標記用於諸如<summary><remarks> <returns> 等標記內,使您得以將結構新增到文字中。

<para>content</para>

content:段落文字。

<code>*

提供了一種插入程式碼的方法。

<code src="src"language="lan"encoding="c"/>

src:程式碼檔案的位置

language:程式碼的計算機語言

encoding:檔案的編碼

<img>*

用以在文件中插入圖片

<imgsrc="src"/>

src:圖片的位置,相對於註釋所在的XML檔案

<file>*

用以在文件中插入檔案,在頁面中表現為下載連結

<filesrc="src"/>

src:檔案的位置,相對於註釋所在的XML檔案

<localize>*

提供一種註釋本地化的方法,名稱與當前執行緒語言不同的子節點將被忽略

<localize>

<zh-CHS>中文</zh-CHS>

<en>English</en>

...

</localize>

五.註釋與幫助文件

完善註釋資訊的最終目的就是為了生成MSDN一樣的程式幫助文件,此文件將在專案整個生命週期中被各種角色使用:開發人員通過此文件維護程式, 測試人員通過此文件瞭解業務邏輯, 專案管理人員將此文件用作專案說明等等.

所以要了解列表中這些不常見的註釋究竟有何作用,就要和最終的幫助文件關聯起來.下面通過示例講解註釋標籤在幫助檔案中的作用.有關如何生成幫助檔案,將在本系列下一篇文章中講解.

先簡單看一下幫助檔案的樣子.我們都看過MSDN幫助文件,使用註釋XML檔案生成的幫助檔案字尾名是chm,開啟後和MSDN基本一樣:

image

本示例的名稱空間是XmlCommentClassDemo, 其中包含兩個類:

UserBL是包含方法的類.

UserInfo是一個模型類.裡面只有UserId和UserName兩個屬性.

(1)類註釋


看一下UserBL類的註釋程式碼:

    /// <summary>
    /// 使用者物件業務邏輯層.
    /// </summary>
    /// <remarks>
    /// 2009.01.01: 建立. ziqiu.zhang <br/>
    /// 2009.01.23: 增加GetUserName和GetUserId方法. ziqiu.zhang <br/> 
    /// </remarks>
    public class UserBL
    {...}

Summary標籤的內容在名稱空間類列表中顯示,如上圖.remarks標籤的內容則顯示在類頁面中,如下圖:

image

對比以前的註釋規範,下面的註釋是我們規定在建立一個新的檔案時需要新增到頭部的註釋:

/***************************************************************************************
 * *
 * *        File Name        : HotelCommentHeaderInfo.cs
 * *        Creator            : ziqiu.zhang
 * *        Create Time        : 2008-09-17
 * *        Functional Description  : 酒店的點評頭模型。包括酒店實體對應的點評頭,酒店的OutHotelInfo資訊
 *                                    ,酒店實體的Tag資訊集合。
 * *        Remark      : 
 * *
 * *  Copyright (c) eLong Corporation.  All rights reserved. 
 * ***************************************************************************************/

新增此註釋塊的目的很好.但是很難推廣.因為這段註釋並不能被編譯器識別,也無法新增到註釋XML檔案中用於生成幫助檔案. 格式不容易記憶,想新增的時候只能從別的複製過來後修改.公司缺少完善的Code Review機制所以最後很多檔案都沒有此註釋塊.

相比較使用.NET自己的註釋語言,不僅"敏捷",而且會成為幫助檔案中的描述.

(2)方法註釋

類的註釋比較簡單.為了樣式常用註釋標籤的效果, 我在方法的註釋中使用了儘可能多的註釋標籤.程式碼如下:

        /// <summary>
        ///     根據使用者Id得到使用者名稱.
        ///     <para>
        ///         此處新增第二段Summary資訊,在MSDN中很少使用.所以不推薦使用.
        ///     </para>  
        /// </summary>
        /// <remarks>
        ///     如果沒有找到使用者則返回null.<br/>
        ///     <paramref name="userId"/> 引數為正整數.<br/>
        ///     使用者Id模型屬性定義參見<see cref="UserInfo.UserId"/><br/>
        ///     相關方法:<seealso cref="UserBL.GetUserId"/>
        /// </remarks>
        /// <param name="userId">使用者Id</param>
        /// <returns>使用者真實姓名</returns>
        /// <example>
        ///     返回使用者id為100的使用者真實姓名:
        ///     <code>
        ///         private string userName = string.Empty;
        ///         userName = UserBL.GetUserName(100);
        ///     </code>
        ///     返回的使用者名稱可能為null,使用時要先判斷:<br/>
        ///     <c>if(userName!=null){...}</c>
        /// </example>
        /// <exception cref="System.ApplicationException">
        ///     如果使用者Id小於0則丟擲此異常
        /// </exception>
        public static string GetUserName(long userId)
        {
            string result = string.Empty;
            if (userId < 0)
            {
                throw new System.ApplicationException();                
            }
            else if (userId == 0)
            {
                result = null;
            }
            else
            {
                result = "Robert";
            }
            return result;
        }

接下來通過圖片進行詳細講解.首先是檢視類成員時的截圖:

image

點選方法後的截圖:

image

需要注意的幾點:

1) 最開始seealso標籤新增在了remarks標籤中,所以在See Also區域沒有新增上方法的連線. 解決方法是把seealso標籤放在summary標籤中.

2) 異常類的cref屬性需要設定成編譯器可以識別的類, 這樣才可以在幫助文件中點選.比如上面的System.ApplicationException異常點選後進入微軟的線上MSDN查詢.如果是自己定義的異常, 需要此異常類也在你的幫助檔案中.一般提供註釋XML和依賴DLL即可.

(3) 屬性的註釋

屬性的註釋也很簡單.和類不同的地方在於屬性要使用<value>標籤而不是<remarks>進行描述:

        private string m_UserName = string.Empty;
        /// <summary>
        /// 使用者真實姓名
        /// </summary>
        /// <value>使用者真實姓名字串.預設值為空.</value>
        public string UserName
        {
            get { return m_UserName; }
            set { m_UserName = value; }
        }

效果如圖:

image

六.總結

本文講解了.NET中的XML註釋標籤, 以及最後在幫助文件中的作用.

瞭解了標籤的使用,在下篇文章中將告訴大家如何使用工具生成本文示例中的幫助檔案.