次の方法で共有


XML API ドキュメントのコメントを生成する

C# ソース ファイルには、これらのファイルで定義されている型の API ドキュメントを生成する構造化コメントを含めることができます。 C# コンパイラは、コメントと API シグネチャを表す構造化データを含む XML ファイルを生成します。 他のツールでは、その XML 出力を処理して、Web ページや PDF ファイルなどの形式で人間が判読できるドキュメントを作成できます。

このプロセスでは、コードに API ドキュメントを追加するための多くの利点があります。

  • C# コンパイラは、C# コードの構造とコメントのテキストを 1 つの XML ドキュメントに結合します。
  • C# コンパイラは、コメントが関連するタグの API シグネチャと一致することを確認します。
  • XML ドキュメント ファイルを処理するツールでは、それらのツールに固有の XML 要素と属性を定義できます。

Visual Studio などのツールは、ドキュメント コメントで使用される多くの一般的な XML 要素に IntelliSense を提供します。

この記事では、次のトピックについて説明します。

  • ドキュメントのコメントと XML ファイルの生成
  • C# コンパイラと Visual Studio によって検証されたタグ
  • 生成された XML ファイルの形式

XML ドキュメントの出力を作成する

コードのドキュメントを作成するには、3 つのスラッシュで示される特別なコメント フィールドを記述します。 コメント フィールドには、コメントに続くコード ブロックを記述する XML 要素が含まれます。 例えば次が挙げられます。

/// <summary>
/// This class performs an important function.
/// </summary>
public class MyClass { }

GenerateDocumentationFile または DocumentationFile オプションを設定すると、コンパイラはソース コードで XML タグを持つすべてのコメント フィールドを検索し、それらのコメントから XML ドキュメント ファイルを作成します。 このオプションを有効にすると、コンパイラは、XML ドキュメント コメントなしでプロジェクトで宣言されているパブリックに表示されるメンバーに対して CS1591 警告を生成します。

XML コメント形式

XML ドキュメント コメントを使用するには、ドキュメント コメントの開始位置と終了位置を示す区切り記号が必要です。 XML ドキュメント タグでは、次の区切り記号を使用します。

  • /// 1 行区切り記号: ドキュメントの例と C# プロジェクト テンプレートでは、この形式が使用されます。 区切り記号の後に空白が続く場合、XML 出力には含まれません。

    コード エディターで///区切り記号を入力すると、Visual Studio によって<summary>タグと</summary>タグが自動的に挿入され、これらのタグ内にカーソルが配置されます。 この機能は、[ オプション] ダイアログ ボックスでオンまたはオフにすることができます。

  • /** */ 複数行区切り記号: /** */ 区切り記号には、次の書式設定規則があります。
    • /**区切り記号を含む行で、残りの行が空白の場合、行はコメント用に処理されません。 /**区切り記号の後の最初の文字が空白の場合、その空白文字は無視され、残りの行が処理されます。 それ以外の場合は、 /** 区切り記号の後の行全体がコメントの一部として処理されます。

    • */区切り記号を含む行では、*/区切り記号までの空白のみが存在する場合、その行は無視されます。 それ以外の場合は、 */ 区切り記号までの行のテキストがコメントの一部として処理されます。

    • /**区切り記号で始まる行の後の行については、コンパイラは各行の先頭で共通のパターンを検索します。 このパターンは、オプションの空白やアスタリスク (*) で構成され、その後にさらに省略可能な空白が続きます。 コンパイラが、 /** 区切り記号で始まらないか、 */ 区切り記号で終わらない共通パターンを各行の先頭で見つけた場合、各行のそのパターンは無視されます。

    • 処理される次のコメントの唯一の部分は、 <summary>で始まる行です。 3 つのタグ形式では、同じコメントが生成されます。

      /** <summary>text</summary> */
      
      /**
      <summary>text</summary>
      */
      
      /**
      * <summary>text</summary>
      */
      
    • コンパイラは、2 行目と 3 行目の先頭にある "* " という共通パターンを識別します。 このパターンは出力に含まれません。

      /**
      * <summary>
      * text </summary>*/
      
    • 3 行目の 2 番目の文字はアスタリスクではないので、コンパイラは次のコメントで共通パターンを見つけることができません。 2 行目と 3 行目のすべてのテキストがコメントの一部として処理されます。

      /**
      * <summary>
         text </summary>
      */
      
    • コンパイラは、次のコメントで 2 つの理由からパターンを検出しません。 まず、アスタリスクの前のスペースの数に一貫性がありません。 次に、5 行目は、スペースと一致しないタブで始まります。 2 行目から 5 行目までのテキストはすべて、コメントの一部として処理されます。

      /**
        * <summary>
        * text
      *  text2
       	*  </summary>
      */
      

XML 要素を参照するには (たとえば、関数は XML ドキュメント コメントで記述する特定の XML 要素を処理します)、標準の引用符メカニズム (&lt;&gt;) を使用できます。 コード参照 (cref) 要素でジェネリック識別子を参照するには、エスケープ文字 ( cref="List&lt;T&gt;" など) または中かっこ (cref="List{T}") を使用できます。 特殊なケースとして、コンパイラは中かっこを山かっことして解析し、一般的な識別子を参照するときに、ドキュメントコメントを作成者にとって煩雑にするのを減らします。

1 行の XML コメント区切り記号 ( ///) を使用してコメントを記述するが、タグを含まない場合、コンパイラはそれらのコメントのテキストを XML 出力ファイルに追加します。 ただし、出力には、 <summary>などの XML 要素は含まれません。 XML コメント (Visual Studio IntelliSense を含む) を使用するほとんどのツールでは、これらのコメントは読み取られません。

XML ドキュメントの入力を受け入れるツール

次のツールは、XML コメントからの出力を作成します。

  • DocFX: DocFX は、現在 C#、Visual Basic、F# をサポートしている .NET 用の API ドキュメント ジェネレーターです。 また、生成された参照ドキュメントをカスタマイズすることもできます。 DocFX は、ソース コードと Markdown ファイルから静的 HTML Web サイトを構築します。 また、DocFX では、テンプレートを使用して Web サイトのレイアウトとスタイルを柔軟にカスタマイズできます。 カスタム テンプレートを作成することもできます。
  • Sandcastle: Sandcastle ツール は、概念と API の両方のリファレンス ページを含むマネージド クラス ライブラリ用のヘルプ ファイルを作成します。 Sandcastle ツールはコマンドライン ベースであり、GUI フロントエンド、プロジェクト管理機能、または自動ビルド プロセスはありません。 Sandcastle ヘルプ ファイル ビルダーには、自動化された方法でヘルプ ファイルを作成するためのスタンドアロンの GUI とコマンド ライン ベースのツールが用意されています。 Visual Studio 統合パッケージも使用できるため、Visual Studio 内からヘルプ プロジェクトを完全に作成および管理できます。
  • Doxygen: Doxygen は、ドキュメント化された一連のソース ファイルからオンライン ドキュメント ブラウザー (HTML) またはオフライン参照マニュアル (LaTeX) を生成します。 RTF (MS Word)、PostScript、ハイパーリンク PDF、圧縮 HTML、DocBook、Unix のマニュアル ページで出力を生成することもできます。 文書化されていないソース ファイルからコード構造を抽出するように Doxygen を構成できます。

XML ドキュメントのコメントはメタデータではありません。これらはコンパイル済みアセンブリに含まれていないため、リフレクションを介してアクセスできません。

ID 文字列

各型またはメンバーは、出力 XML ファイル内の要素に格納されます。 これらの各要素には、型またはメンバーを識別する一意の ID 文字列があります。 ID 文字列は、演算子、パラメーター、戻り値、ジェネリック型パラメーター、 refin、および out パラメーターを考慮する必要があります。 これらの潜在的なすべての要素をエンコードするために、コンパイラは、ID 文字列を生成するための明確に定義された規則に従います。 XML ファイルを処理するプログラムは、ID 文字列を使用して、ドキュメントが適用される対応する .NET メタデータまたはリフレクション項目を識別します。

コンパイラは、ID 文字列を生成するときに、次の規則を確認します。

  • 文字列内に空白はありません。

  • 文字列の最初の部分では、1 文字の後にコロンを使用してメンバーの種類を識別します。 次のメンバー型が使用されます。

    キャラクター メンバーの種類 注記
    N 名前空間 名前空間にドキュメント コメントを追加することはできませんが、サポートされている場合は、 cref 参照を作成できます。
    T 型は、クラス、インターフェイス、構造体、列挙型、またはデリゲートです。
    F フィールド
    P プロパティ インデクサーまたはその他のインデックス付きプロパティが含まれます。
    M メソッド コンストラクターや演算子などの特殊なメソッドが含まれます。
    E イベント
    ! エラー文字列 残りの文字列は、エラーに関する情報を提供します。 C# コンパイラは、解決できないリンクのエラー情報を生成します。
  • 文字列の 2 番目の部分は、名前空間のルートから始まる項目の完全修飾名です。 項目の名前、その外側の型、および名前空間はピリオドで区切られます。 項目自体の名前にピリオドがある場合は、ハッシュ記号 ('#') に置き換えられます。 文法では、名前に直接ハッシュ記号を持つ項目がないことを前提としています。 たとえば、String コンストラクターの完全修飾名は "System.String.#ctor" です。

  • プロパティとメソッドの場合、かっこで囲まれたパラメーター リストは次のようになります。 パラメーターがない場合、かっこは存在しません。 パラメーターはコンマで区切られます。 各パラメーターのエンコードは、.NET シグネチャでのエンコード方法に直接従います (次の一覧のすべての caps 要素の定義については、 Microsoft.VisualStudio.CorDebugInterop.CorElementType を参照してください)。

    • 基本型。 通常の型 (ELEMENT_TYPE_CLASS または ELEMENT_TYPE_VALUETYPE) は、型の完全修飾名として表されます。
    • 組み込み型 ( ELEMENT_TYPE_I4ELEMENT_TYPE_OBJECTELEMENT_TYPE_STRINGELEMENT_TYPE_TYPEDBYREFELEMENT_TYPE_VOIDなど) は、対応する完全型の完全修飾名として表されます。 たとえば、System.Int32 または System.TypedReference です。
    • ELEMENT_TYPE_PTR は、変更された型に続く '*' として表されます。
    • ELEMENT_TYPE_BYREF は、変更された型の後に '@' として表されます。
    • ELEMENT_TYPE_CMOD_OPT は、変更された型に続く修飾子クラスの '!' と完全修飾名として表されます。
    • ELEMENT_TYPE_SZARRAY は、配列の要素型の後に "[]" として表されます。
    • ELEMENT_TYPE_ARRAY は [lower bound:size,lower bound:size] として表されます。コンマの数はランク - 1 で、各ディメンションの下限とサイズ (既知の場合) は 10 進数で表されます。 下限とサイズが指定されていない場合は省略されます。 特定のディメンションの下限とサイズを省略すると、':' も省略されます。 たとえば、下限が 1 でサイズが指定されていない 2 次元配列は [1:,1:] です。
  • 変換演算子のみの場合 (op_Implicit および op_Explicit)、メソッドの戻り値は ~ としてエンコードされ、その後に戻り値の型が続きます。 たとえば、<member name="M:System.Decimal.op_Explicit(System.Decimal arg)~System.Int32">は、System.Decimal クラスで宣言public static explicit operator int (decimal value);キャスト演算子のタグです。

  • ジェネリック型の場合、型の名前の後にバックティックが続き、ジェネリック型パラメーターの数を示す数値が続きます。 たとえば、 <member name="T:SampleClass`2"> は、 public class SampleClass<T, U>として定義されている型のタグです。 ジェネリック型をパラメーターとして受け取るメソッドの場合、ジェネリック型パラメーターはバッククォークで始まる数値として指定されます (例: '0,'1)。 各数値は、型のジェネリック パラメーターの 0 から始まる配列表記を表します。

    • ELEMENT_TYPE_PINNED は、変更された型の後に '^' として表されます。 C# コンパイラでは、このエンコーディングは生成されません。
    • ELEMENT_TYPE_CMOD_REQ は、変更された型に続く修飾子クラスの '|' と完全修飾名として表されます。 C# コンパイラでは、このエンコーディングは生成されません。
    • ELEMENT_TYPE_GENERICARRAY は、配列の要素型の後に "[?]" として表されます。 C# コンパイラでは、このエンコーディングは生成されません。
    • ELEMENT_TYPE_FNPTR は "=FUNC:type(シグネチャ)" として表されます。ここで、 type は戻り値の型で、 シグネチャ はメソッドの引数です。 引数がない場合、かっこは省略されます。 C# コンパイラでは、このエンコーディングは生成されません。
    • 次のシグネチャ コンポーネントは、オーバーロードされたメソッドを区別するために使用されないため、表されません。
      • 呼び出し規則
      • 戻り値の型
      • ELEMENT_TYPE_SENTINEL

次の例は、クラスとそのメンバーの ID 文字列がどのように生成されるかを示しています。

namespace MyNamespace;

/// <summary>
/// Enter description here for class X.
/// ID string generated is "T:MyNamespace.MyClass".
/// </summary>
public unsafe class MyClass
{
    /// <summary>
    /// Enter description here for the first constructor.
    /// ID string generated is "M:MyNamespace.MyClass.#ctor".
    /// </summary>
    public MyClass() { }

    /// <summary>
    /// Enter description here for the second constructor.
    /// ID string generated is "M:MyNamespace.MyClass.#ctor(System.Int32)".
    /// </summary>
    /// <param name="i">Describe parameter.</param>
    public MyClass(int i) { }

    /// <summary>
    /// Enter description here for field Message.
    /// ID string generated is "F:MyNamespace.MyClass.Message".
    /// </summary>
    public string? Message;

    /// <summary>
    /// Enter description for constant PI.
    /// ID string generated is "F:MyNamespace.MyClass.PI".
    /// </summary>
    public const double PI = 3.14;

    /// <summary>
    /// Enter description for method Func.
    /// ID string generated is "M:MyNamespace.MyClass.Func".
    /// </summary>
    /// <returns>Describe return value.</returns>
    public int Func() => 1;

    /// <summary>
    /// Enter description for method SomeMethod.
    /// ID string generated is "M:MyNamespace.MyClass.SomeMethod(System.String,System.Int32@,System.Void*)".
    /// </summary>
    /// <param name="str">Describe parameter.</param>
    /// <param name="num">Describe parameter.</param>
    /// <param name="ptr">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public int SomeMethod(string str, ref int num, void* ptr) { return 1; }

    /// <summary>
    /// Enter description for method AnotherMethod.
    /// ID string generated is "M:MyNamespace.MyClass.AnotherMethod(System.Int16[],System.Int32[0:,0:])".
    /// </summary>
    /// <param name="array1">Describe parameter.</param>
    /// <param name="array">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public int AnotherMethod(short[] array1, int[,] array) { return 0; }

    /// <summary>
    /// Enter description for operator.
    /// ID string generated is "M:MyNamespace.MyClass.op_Addition(MyNamespace.MyClass,MyNamespace.MyClass)".
    /// </summary>
    /// <param name="first">Describe parameter.</param>
    /// <param name="second">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public static MyClass operator +(MyClass first, MyClass second) { return first; }

    /// <summary>
    /// Enter description for property.
    /// ID string generated is "P:MyNamespace.MyClass.Prop".
    /// </summary>
    public int Prop { get { return 1; } set { } }

    /// <summary>
    /// Enter description for event.
    /// ID string generated is "E:MyNamespace.MyClass.OnHappened".
    /// </summary>
    public event Del? OnHappened;

    /// <summary>
    /// Enter description for index.
    /// ID string generated is "P:MyNamespace.MyClass.Item(System.String)".
    /// </summary>
    /// <param name="str">Describe parameter.</param>
    /// <returns></returns>
    public int this[string s] => 1;

    /// <summary>
    /// Enter description for class Nested.
    /// ID string generated is "T:MyNamespace.MyClass.Nested".
    /// </summary>
    public class Nested { }

    /// <summary>
    /// Enter description for delegate.
    /// ID string generated is "T:MyNamespace.MyClass.Del".
    /// </summary>
    /// <param name="i">Describe parameter.</param>
    public delegate void Del(int i);

    /// <summary>
    /// Enter description for operator.
    /// ID string generated is "M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Int32".
    /// </summary>
    /// <param name="myParameter">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public static explicit operator int(MyClass myParameter) => 1;
}

C# 言語仕様

詳細については、ドキュメント コメントの C# 言語仕様 の付録を参照してください。