2013-08-03T01:11:53の更新内容

programming/netfx/classlibrary/2_xmldoccomments/index.wiki.txt

current previous
1,11 1,11
 
${smdncms:title,XMLドキュメントコメントを用いたドキュメントの作成}
${smdncms:title,XMLドキュメントコメントを用いたドキュメントの作成}
~
${smdncms:keywords,XMLドキュメントコメント,XMLコメント,IntelliSense,インテリセンス,リファレンス,ドキュメント,仕様,作成}
${smdncms:keywords,XMLドキュメントコメント,XMLコメント,IntelliSense,リファレンス,ドキュメント,仕様,作成}
 

        

        
 
#navi(..)
#navi(..)
 

        

        
~
クラスライブラリなどを提供する場合、同時に使い方や詳細な仕様をまとめたドキュメント(APIリファレンス)も提供する場合があります。 これらを個別に作成・メンテナンスすることも出来ますが、バージョンアップを重ねる度に実装とドキュメントの内容の同期を取るのは手間のかかる作業です。
クラスライブラリなどを提供する場合、同時に使い方や詳細な仕様をまとめたドキュメントも提供する場合があります。 これらを個別に作成・メンテナンスすることも出来ますが、バージョンアップを重ねる度に実装とドキュメントの内容の同期を取るのは手間のかかる作業です。
 

        

        
~
これを解決する一つの方法として、ソースコード中にコメントとして直接APIのリファレンスを記述することで、実装とドキュメントの同期をしやすくするというやり方があります。 この場合、コメントからドキュメントを作成する方法が問題となってきます。 Doxygenなどこの様な機能を提供する専用のツールは存在しますが、C#およびVBコンパイラではこの様な要求を満たすXMLドキュメントコメントという機能がコンパイラの機能として用意されています。 XMLドキュメントコメントは、Javadocと同様の機能を提供するものです。
これを解決する一つの方法として、ソースコード中にコメントとして直接ドキュメントを記述することで、実装とドキュメントの同期をしやすくするというやり方があります。 この場合、コメントからドキュメントを作成する方法が問題となってきます。 Doxygenなどこの様な機能を提供する専用のツールは存在しますが、C#およびVBコンパイラではこの様な要求を満たすXMLドキュメントコメントという機能がコンパイラの機能として用意されています。
 

        

        
 
ここではXMLドキュメントコメントの記述方法と、XMLドキュメントコメントを使ったドキュメントの生成方法について解説します。
ここではXMLドキュメントコメントの記述方法と、XMLドキュメントコメントを使ったドキュメントの生成方法について解説します。
 

        

        
36,29 36,7
 
}
}
 
}}
}}
 

        

        
~
2つの//(スラッシュ)で始まる行は通常のコメント、3つの///で始まる行がXMLドキュメントコメントです。
2つの/(スラッシュ)で始まる行は通常のコメント、3つの///で始まる行がXMLドキュメントコメントです。
+

          
+
次のようにJavadocのような「/** 〜 */」の形式のコメントもXMLドキュメントコメントとして扱われます。 当然、「/* 〜 */」は通常のコメントとして扱われます。
+

          
+
#code{{
+
using System;
+

          
+
/**
+
<summary>XMLドキュメントコメントを使ったサンプルです。</summary>
+
*/
+
class Sample
+
{
+
  /**
+
  <summary>アプリケーションのメイン エントリ ポイントです。</summary>
+
  */
+
  static void Main()
+
  {
+
    /* メッセージを表示します */
+
    Console.WriteLine("Hello, world");
+
  }
+
}
+
}}
+

          
 
#tabpage(codelang=vb)
#tabpage(codelang=vb)
 
#code{{
#code{{
 
Imports System
Imports System
163,60 141,30
 
ここで使用した要素、およびよく使われる要素とその用途・意味を以下の表にまとめておきます。
ここで使用した要素、およびよく使われる要素とその用途・意味を以下の表にまとめておきます。
 

        

        
 
|*XMLドキュメントコメントの要素
|*XMLドキュメントコメントの要素
~
|>|~要素|~形式|~用途と意味|h
|~要素|~形式|~用途と意味|h
~
|~説明文のセクションを構成する要素|~summary要素|<summary>...</summary>|{{
|>|>|~説明文を記述するための要素|
~
型やメンバに関する説明・概要を記述します。
|~summary要素|<summary>...</summary>|型やメンバに関する説明・概要を記述します。&br;この要素は他の要素を含むことも出来、他の型やメンバへのリンクとなるsee要素や段落を表すpara要素などを使って記述することが出来ます。|
~

          
|~remarks要素|<remarks>...</remarks>|型やメンバに関する補足的な追加の情報を記述します。&br;この要素でsummary要素の記述を補足します。 summary要素と同様、see要素やpara要素を使って記述する事も出来ます。|
~
この要素は他の要素を含むこともでき、他の型やメンバへのリンクとなるsee要素や段落を表すpara要素などを使ってマークアップすることが出来ます。
|~param要素|<param name="name">...</param>|指定された引数nameに関する説明を記述します。&br;この要素で引数に指定できる値や、値域についての説明を記述します。 ArgumentExceptionなどの例外について記述するにはexception要素を使います。|
~
この要素で記述された内容はIntelliSenseで表示されるようになるため、この要素では型やメンバについての簡単な(1行程度の)説明にとどめ、より詳細な動作や使用上の注意点などはremarks要素で記述するようにします。
|~returns要素|<returns>...</returns>|メソッドの戻り値に関する説明を記述します。|
~
}}|
|~exception要素|<exception cref="member">...</exception>|メンバがスローする例外に関する説明を記述します。&br;cref属性でスローする例外、要素のテキストでその例外がスローされる理由・状況についての説明を記述します。 cref属性の指定方法は[[メンバのID>#xmlelement_memberid]]で解説します。|
~
|~|~remarks要素|<remarks>...</remarks>|{{
|~example要素|<example>...</example>|型やメンバの使用例について記述します。&br;see要素やpara要素の他に、インラインのコードはc要素、複数行にまたがるコードはcode要素を使って記述することが出来ます。|
~
型やメンバに関する補足的な追加の情報を記述します。
|~value要素|<value>...</value>|プロパティが表す値について記述します。|
~

          
|>|>|~リンクを作成するための要素|
~
この要素でsummary要素の記述を補足します。 summary要素と同様、see要素やpara要素を使ってマークアップする事が出来ます。
|~paramref要素|<paramref name="name"/>|指定された引数nameの説明へのリンクを指定します。|
~
}}|
|~see要素|<see cref="member"/>|指定されたメンバmemberへのリンクを指定します。 memberには任意の型やメソッドを指定することが出来ます。 cref属性の指定方法は[[メンバのID>#xmlelement_memberid]]で解説します。|
~
|~|~param要素|<param name="&var{name};">...</param>|{{
|>|>|~説明文の文書構造を定義するための要素|
~
指定された引数&var{name};に関する説明を記述します。
|~para要素|<para>...</para>|説明文の段落を定義します。 これはXHTML/HTMLのp要素やdiv要素に相当する要素です。|
~

          
|~c要素|<c>...</c>|インラインで表示されるコードを記述します。 説明文中の変数名やメソッド名などを修飾する場合に使います。|
~
この要素でメソッドの引数に指定できる値や、値域についての説明を記述します。 ArgumentExceptionなど引数の例外について記述するにはexception要素を使います。
|~code要素|<code>...</code>|複数行のコードを記述します。|
+
}}|
+
|~|~typeparam要素|<typeparam name="&var{name};">...</typeparam>|ジェネリック型やジェネリックメソッドにおいて、指定された型パラメータ&var{name};に関する説明を記述します。|
+
|~|~returns要素|<returns>...</returns>|メソッドの戻り値に関する説明を記述します。|
+
|~|~exception要素|<exception cref="&var{member};">...</exception>|{{
+
メンバがスローする例外に関する説明を記述します。
+

          
+
cref属性でスローする例外の型を、要素のテキストでその例外がスローされる理由・状況についての説明を記述します。 cref属性の指定方法は[[メンバのID>#xmlelement_memberid]]で解説します。
+
}}|
+
|~|~example要素|<example>...</example>|{{
+
型やメンバの使用例について記述します。
+

          
+
see要素やpara要素の他に、インラインのコードはc要素、複数行にまたがるコードはcode要素を使って記述することが出来ます。
+
}}|
+
|~|~value要素|<value>...</value>|プロパティが表す値について記述します。|
+
|~|~seealso要素|<seealso cref="&var{member};"/>|{{
+
指定されたメンバ&var{member};へのリンクを「参照」セクションの関連項目に追加します。
+

          
+
seealso要素を使うことで、親クラスやオーバーロードされた他のメソッド、類似するメンバなどのリンクの一覧を記述することができます。 cref属性の指定方法は[[メンバのID>#xmlelement_memberid]]で解説します。
+
seealso要素は他の要素とは異なり説明文を記述することはできません。 また、seealso要素は説明文中でメンバへのリンクを記述するsee要素とは異なります。
+
}}|
+
|~リンクを作成するための要素|~see要素|<see cref="&var{member};"/>|指定されたメンバ&var{member};へのリンクを指定します。 &var{member};には任意の型やメソッドを指定することが出来ます。 cref属性の指定方法は[[メンバのID>#xmlelement_memberid]]で解説します。|
+
|~|~paramref要素|<paramref name="&var{name};"/>|指定された引数&var{name};の説明へのリンクを指定します。|
+
|~|~typeparamref要素|<typeparamref name="&var{name};"/>|指定された型パラメータ&var{name};の説明へのリンクを指定します。|
+
|~説明文内でのマークアップを行う要素|~para要素|<para>...</para>|説明文の段落を定義します。 これはXHTML/HTMLのp要素やdiv要素に相当する要素です。|
+
|~|~code要素|<code>...</code>|1行以上の複数行にわたるコードを記述します。 説明文中でサンプルコードを提示する場合に使います。|
+
|~|~c要素|<c>...</c>|インラインで表示されるコードを記述します。 説明文中の変数名やメソッド名などをマークアップする場合に使います。|
 

        

        
~
summaryなど説明文のセクションを構成する要素は常に最上位の要素でなければならず、互いに他の要素の子要素として入れ子にしたりすることはできません。 例えば、remarks要素の中にexample要素を含めたりすることはできません。
上記以外にも、型パラメータについて記述するtypeparam要素やリスト構造を作成するlist要素、他のドキュメントを読み込むinclude要素などがあります。 詳細は以下のドキュメントを参照してください。
+

          
+
それ以外の要素はsummary要素やexample要素に含めて記述することができます。 例えば、remarks要素やexample要素の説明文中でサンプルコードを記述したい場合にはcode要素を使います。
+

          
+
上記以外にも、メンバのアクセス許可に関する説明を記述するpermission要素、リスト構造を作成するlist要素、[[他のドキュメントを読み込むinclude要素>#include_document]]などがあります。 詳細は以下のドキュメントを参照してください。
 
-&msdn(netfx,id,5ast78ax){ドキュメント コメントとして推奨される XML タグ (C# プログラミング ガイド)};
-&msdn(netfx,id,5ast78ax){ドキュメント コメントとして推奨される XML タグ (C# プログラミング ガイド)};
 
-&msdn(netfx,id,ms172653){ドキュメント コメントとして推奨される XML タグ (Visual Basic)};
-&msdn(netfx,id,ms172653){ドキュメント コメントとして推奨される XML タグ (Visual Basic)};
 

        

        
 
このようにして記述したXMLドキュメントコメントは、前述したとおり[[IDEの入力候補等でも表示>#idecomplement]]されるようになります。
このようにして記述したXMLドキュメントコメントは、前述したとおり[[IDEの入力候補等でも表示>#idecomplement]]されるようになります。
 

        

        
~
なお、先に挙げたのコードをコンパイルすると、以下のようなXMLドキュメントが生成されます。
なお、上記のコードをコンパイルすると、以下のようなXMLドキュメントが生成されます。
 

        

        
 
#code(xml,コンパイラが出力するXMLドキュメント){{
#code(xml,コンパイラが出力するXMLドキュメント){{
 
<?xml version="1.0"?>
<?xml version="1.0"?>
254,197 202,44
 
}}
}}
 

        

        
 
**メンバのID [#xmlelement_memberid]
**メンバのID [#xmlelement_memberid]
~
see要素やexception要素ではcref属性で型やメンバのIDを指定することにより、リンクを作成することが出来ます。 このIDは、「&var{メンバの種類};:&var{完全限定名};」の形式で定義されています。 メンバの種類は一文字で表され、型を表す''T''やメソッドを表す''M''などを指定します。 例えば、型であれば「T:&var{名前空間};.&var{型名};」となり、メソッドであれば「M:&var{名前空間};.&var{型名};.&var{メソッド名};(&var{引数リスト};)」のようになります。
see要素やexception要素ではcref属性で型やメンバのIDを指定することにより、リンクを作成することが出来ます。 このIDは、「メンバの種類:完全限定名」の形式で定義されています。 メンバの種類は一文字で表され、型やメソッドなどを指定します。 IDの規則といくつかの例を表にまとめると次のようになります。
+

          
+
IDの規則といくつかの例を表にまとめると次のようになります。
 

        

        
 
|*IDの規則
|*IDの規則
~
|>|>|~IDの例|h
|~IDの例|~IDが表すメンバ|h
~
|~種類|~例|~IDが表すメンバ|h
|>|~N (名前空間)|
~
|~N (名前空間)|N:System.Collections|System.Collections名前空間|
|N:System.Collections|System.Collections名前空間|
~
|~T (型)&br;クラス/インターフェイス/構造体/列挙体/デリゲート|T:System.String|Stringクラス|
|>|~T (型、クラス/インターフェイス/構造体/列挙体/デリゲート)|
~
|~|T:System.ArgumentException|ArgumentException例外クラス|
|T:System.String|Stringクラス|
~
|~|T:System.StringComparison|StringComparison列挙体|
|T:System.ArgumentException|ArgumentException例外クラス|
~
|~|T:System.IDisposable|IDisposableインターフェイス|
|T:System.StringComparison|StringComparison列挙体|
~
|~|T:System.EventHandler|EventHandlerデリゲート|
|T:System.IDisposable|IDisposableインターフェイス|
~
|~|T:System.Collections.Generic.List`1|List<T>ジェネリッククラス|
|T:System.EventHandler|EventHandlerデリゲート|
~
|~|T:System.Action`1|Action<T>ジェネリックデリゲート|
|T:System.Collections.Generic.List`1|List<T>ジェネリッククラス|
~
|~|T:System.Action`2|Action<T1, T2>ジェネリックデリゲート|
|T:System.Action`1|Action<T>ジェネリックデリゲート|
~
|~M (メソッド)&br;メソッド/コンストラクタ/オーバーロードされた演算子|M:System.String.ToUpper|String.ToUpperメソッド|
|T:System.Action`2|Action<T1, T2>ジェネリックデリゲート|
~
|~|M:System.String.IndexOf(System.String)|String.IndexOf(string)メソッド|
|>|~M (メソッド、メソッド/コンストラクタ/オーバーロードされた演算子)|
~
|~|M:System.String.IndexOf(System.String,System.Int32)|String.IndexOf(string, int)メソッド|
|M:System.String.IndexOf(System.String)|String.IndexOf(string)メソッド|
~
|~|M:System.String.#ctor(System.Char[])|String(char[])コンストラクタ|
|M:System.String.IndexOf(System.String,System.Int32)|String.IndexOf(string, int)メソッド|
~
|~|M:System.String.#ctor(System.Char,System.Int32)|String(char, int)コンストラクタ|
|M:System.String.#ctor(System.Char[])|String(char[])コンストラクタ|
~
|~|M:System.String.op_Equality(System.String,System.String)|Stringクラスの等価演算子==|
|M:System.String.#ctor(System.Char,System.Int32)|String(char, int)コンストラクタ|
~
|~P (プロパティ)&br;プロパティ/インデクサ|P:System.String.Length|String.Lengthプロパティ|
|M:System.String.op_Equality(System.String,System.String)|Stringクラスの等価演算子==|
~
|~|P:System.String.Chars(String.Int32)|String.Charsプロパティ (インデクサ)|
|>|~P (プロパティ、プロパティ/インデクサ)|
~
|~|P:System.Collections.Generic.List`1.Count|List<T>.Countプロパティ|
|P:System.String.Length|String.Lengthプロパティ|
~
|~F (フィールド)|F:System.IO.Path.DirectorySeparatorChar|Path.DirectorySeparatorCharフィールド|
|P:System.String.Chars(String.Int32)|String.Charsプロパティ (インデクサ)|
~
|~E (イベント)|E:System.Windows.Form.Control.Click|Control.Clickイベント|
|P:System.Collections.Generic.List`1.Count|List<T>.Countプロパティ|
-
|>|~F (フィールド)|
-
|F:System.IO.Path.DirectorySeparatorChar|Path.DirectorySeparatorCharフィールド|
-
|>|~E (イベント)|
-
|E:System.Windows.Form.Control.Click|Control.Clickイベント|
 

        

        
~
その他、メンバIDの規則の詳細については以下のドキュメントにまとめられています。
メンバのIDの詳細については、以下のドキュメントにまとめられています。
 
-&msdn(netfx,id,fsbx0t7x){XML ファイルの処理 (C# プログラミング ガイド)};
-&msdn(netfx,id,fsbx0t7x){XML ファイルの処理 (C# プログラミング ガイド)};
 
-&msdn(netfx,id,ms172673){XML ファイルの処理 (Visual Basic)};
-&msdn(netfx,id,ms172673){XML ファイルの処理 (Visual Basic)};
 

        

        
~
***ジェネリック型・ジェネリックメソッドのID
**独自の要素・属性とXMLドキュメントの拡張
+
ジェネリック型の型名を表記する場合、コード中で使用される山カッコ ''< >'' ではなくバッククォート ''`'' と型パラメータの''数''を使って表記します。 例えば、List<T>は型パラメータの数が''1''なのでIDは次のようになります。
+
#code{{
+
System.Collections.Generic.List<T>
+
              |
+
              V
+
T:System.Collections.Generic.List`1
+
}}
+

          
+
同様に、Dictionary<TKey, TValue>.Countプロパティでは型パラメータの数が''2''なのでIDは次のようになります。
+

          
+
#code{{
+
System.Collections.Generic.Dictionary<TKey, TValue>.Count
+
              |
+
              V
+
P:System.Collections.Generic.Dictionary`2.Count
+
}}
+

          
+
ジェネリックメソッドの場合は、バッククォート2つに続けて型パラメータの数を指定します。 また、引数で型パラメータを参照するにはバッククォート2つに続けて0から始まる型パラメータのインデックスを指定します。 例えばSystem.Linq.Enumerable.SelectメソッドのIDは次のようになります。
+
#code{{
+
System.Linq.Enumerable.Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>)
+
              |
+
              V
+
M:System.Linq.Enumerable.Select``2(System.Collections.Generic.IEnumerable{``0},System.Func{``0,``1})
+
}}
+

          
+
***メソッドの引数リストとID
+
メソッドのrefパラメータやoutパラメータは、ともに型名の後ろにアットマーク ''@'' を付けます。 ポインタ型の場合は型名の後ろにアスタリスク ''*'' を付けます
+

          
+
#code{{
+
FooNamespace.BarClass.BazMethod(ref int, out int, int*)
+
              |
+
              V
+
M:FooNamespace.BarClass.BazMethod(System.Int32@,System.Int32@,System.Int32*)
+
}}
+

          
+
配列(ジャグ配列や多次元配列)の場合は次のようになります。 多次元配列では各次元でのインデックスの下限を表す ''0:'' を記述する必要があります。
+

          
+
#code{{
+
FooNamespace.BarClass.BazMethod(int[], int[][], int[,])
+
              |
+
              V
+
M:FooNamespace.BarClass.BazMethod(System.Int32[],System.Int32[][],System.Int32[0:,0:])
+
}}
+

          
+
**外部ドキュメントのインクルード (include要素) [#include_document]
+
XMLドキュメントコメントでは、&msdn(netfx,id,9h8dy30z){include要素};を使うことで外部のXMLファイルからドキュメントをインクルードすることができます。 include要素を使うことでドキュメントをソースコード上ではなく別のファイルで管理したり、ソース上の複数箇所で同じ説明文が記述されることがないよう定型文を外部ファイル化したりすることができます。
+

          
+
include要素は``<include file="&var{filename};" path="&var{xpath};"/>``のように記述します。 ドキュメントの生成時に、XMLファイル&var{filename};からXPath式&var{xpath};で表される要素の内容が読み込まれ、include要素が記述された位置にインクルードされます。
+

          
+
include要素を使った例を見てみます。 まず、次のようなメソッド郡と、XMLドキュメントコメントを記述します。 ソースコード中には、引数の型だけが異なり、機能的には同一のメソッドが記述されています。 このメソッドではsummary要素やparam要素の内容は共通なので、これらを外部のファイルで記述することにします。 ここでは、ファイルMathUtils.xmlに記述した内容をインクルードするようにします。
+

          
+
#tabpage(codelang=cs,container-title=引数の型だけが異なるメソッド郡を含むソースコード)
+
#code{{
+
using System;
+

          
+
public static class MathUtils
+
{
+
  /// <include file="MathUtils.xml" path="MathUtils/Max/*"/>
+
  /// <returns>引数で与えられた3つの<see cref="T:System.Int32"/>のうち、最大のものを返します。</returns>
+
  public static int Max(int x, int y, int z)
+
  {
+
    return Math.Max(Math.Max(x, y), z);
+
  }
+

          
+
  /// <include file="MathUtils.xml" path="MathUtils/Max/*"/>
+
  /// <returns>引数で与えられた3つの<see cref="T:System.Int64"/>のうち、最大のものを返します。</returns>
+
  public static long Max(long x, long y, long z)
+
  {
+
    return Math.Max(Math.Max(x, y), z);
+
  }
+

          
+
  /// <include file="MathUtils.xml" path="MathUtils/Max/*"/>
+
  /// <returns>引数で与えられた3つの<see cref="T:System.Double"/>のうち、最大のものを返します。</returns>
+
  public static double Max(double x, double y, double z)
+
  {
+
    return Math.Max(Math.Max(x, y), z);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+

          
+
Public Module MathUtils
+
  ''' <include file="MathUtils.xml" path="MathUtils/Max/*"/>
+
  ''' <returns>引数で与えられた3つの<see cref="T:System.Int32"/>のうち、最大のものを返します。</returns>
+
  Public Function Max(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As Integer
+
    Return Math.Max(Math.Max(x, y), z)
+
  End Function
+

          
+
  ''' <include file="MathUtils.xml" path="MathUtils/Max/*"/>
+
  ''' <returns>引数で与えられた3つの<see cref="T:System.Int64"/>のうち、最大のものを返します。</returns>
+
  Public Function Max(ByVal x As Long, ByVal y As Long, ByVal z As Long) As Long
+
    Return Math.Max(Math.Max(x, y), z)
+
  End Function
+

          
+
  ''' <include file="MathUtils.xml" path="MathUtils/Max/*"/>
+
  ''' <returns>引数で与えられた3つの<see cref="T:System.Double"/>のうち、最大のものを返します。</returns>
+
  Public Function Max(ByVal x As Double, ByVal y As Double, ByVal z As Double) As Double
+
    Return Math.Max(Math.Max(x, y), z)
+
  End Function
+
End Module
+
}}
+
#tabpage-end
+

          
+
インクルードするMathUtils.xmlの内容は次のようにします。 include要素のpath属性ではXPath式``MathUtils/Max/*``を指定しているため、このファイルに記述されている「MathUtils要素配下の(``MathUtils/``)、Max要素配下にある(``Max/``)、すべての要素(``*``)」がインクルードされます。
+

          
+
#code(xml,共通する内容を記述したファイル){{
+
<?xml version="1.0"?>
+
<MathUtils>
+
  <Max>
+
    <summary>引数で与えられた3つの値のうち、最大のものを返します。</summary>
+
    <param name="x">比較する3つの値のうち、1つ目の値。</param>
+
    <param name="y">比較する3つの値のうち、2つ目の値。</param>
+
    <param name="z">比較する3つの値のうち、3つ目の値。</param>
+
  </Max>
+
</MathUtils>
+
}}
+

          
+
このように記述されたソースコードからは、次のようなXMLドキュメントが生成されます。
+

          
+
#code(xml,生成されるXMLドキュメント){{
+
<?xml version="1.0"?>
+
<doc>
+
    <assembly>
+
        <name>test</name>
+
    </assembly>
+
    <members>
+
        <member name="M:MathUtils.Max(System.Int32,System.Int32,System.Int32)">
+
            <summary>引数で与えられた3つの値のうち、最大のものを返します。</summary>
+
            <param name="x">比較する3つの値のうち、1つ目の値。</param>
+
            <param name="y">比較する3つの値のうち、2つ目の値。</param>
+
            <param name="z">比較する3つの値のうち、3つ目の値。</param>
+
            <returns>引数で与えられた3つの<see cref="T:System.Int32" />のうち、最大のものを返します。</returns>
+
        </member>
+
        <member name="M:MathUtils.Max(System.Int64,System.Int64,System.Int64)">
+
            <summary>引数で与えられた3つの値のうち、最大のものを返します。</summary>
+
            <param name="x">比較する3つの値のうち、1つ目の値。</param>
+
            <param name="y">比較する3つの値のうち、2つ目の値。</param>
+
            <param name="z">比較する3つの値のうち、3つ目の値。</param>
+
            <returns>引数で与えられた3つの<see cref="T:System.Int64" />のうち、最大のものを返します。</returns>
+
        </member>
+
        <member name="M:MathUtils.Max(System.Double,System.Double,System.Double)">
+
            <summary>引数で与えられた3つの値のうち、最大のものを返します。</summary>
+
            <param name="x">比較する3つの値のうち、1つ目の値。</param>
+
            <param name="y">比較する3つの値のうち、2つ目の値。</param>
+
            <param name="z">比較する3つの値のうち、3つ目の値。</param>
+
            <returns>引数で与えられた3つの<see cref="T:System.Double" />のうち、最大のものを返します。</returns>
+
        </member>
+
    </members>
+
</doc>
+
}}
+

          
+

          
+
**独自の要素・属性とXMLドキュメントの拡張 [#document_extension]
 
XMLドキュメントコメントでは、妥当なXMLである限り上記以外の要素や属性を使って記述することが出来ます。 例えば、以下のようにXML名前空間を使って独自の属性を埋め込んだり、XHTMLの要素を使ってドキュメントを記述するといったことが出来ます。
XMLドキュメントコメントでは、妥当なXMLである限り上記以外の要素や属性を使って記述することが出来ます。 例えば、以下のようにXML名前空間を使って独自の属性を埋め込んだり、XHTMLの要素を使ってドキュメントを記述するといったことが出来ます。
 

        

        
~
#code(cs,独自の要素・属性を使ってマークアップしたドキュメントの例){{
#code(cs){{
 
/// <summary xml:lang="ja">1つめ<see cref="T:System.String"/></summary>
/// <summary xml:lang="ja">1つめ<see cref="T:System.String"/></summary>
 
/// <summary>2つめ<see cref="T:System.String" x:version="netfx2.0" xmlns:x="http://example.com/ns/extensions"/></summary>
/// <summary>2つめ<see cref="T:System.String" x:version="netfx2.0" xmlns:x="http://example.com/ns/extensions"/></summary>
 
/// <summary xml:lang="en">3rd<see cref="T:System.String"/></summary>
/// <summary xml:lang="en">3rd<see cref="T:System.String"/></summary>
464,7 259,7
 

        

        
 
上記のコードからは次のようなXMLドキュメントが生成されます。
上記のコードからは次のようなXMLドキュメントが生成されます。
 

        

        
~
#code(xml,生成されるXMLドキュメント){{
#code(xml){{
 
<?xml version="1.0"?>
<?xml version="1.0"?>
 
<doc>
<doc>
 
    <assembly>
    <assembly>
528,7 323,7
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
~
なお、2013年08月現在のvbncではXMLドキュメントの生成はサポートされていません。
なお、2010年11月現在のvbncではXMLドキュメントの生成はサポートされていません。
 

        

        
 
**IDEでの設定
**IDEでの設定
 
ここではXMLドキュメントを生成するためのIDEでの設定方法について見ていきます。
ここではXMLドキュメントを生成するためのIDEでの設定方法について見ていきます。
554,7 349,7
 

        

        
 

        

        
 
*XMLドキュメントの整形とHTMLへの変換
*XMLドキュメントの整形とHTMLへの変換
~
XMLドキュメントを整形したり他の形式に変換するツールには[[Sandcastle:http://sandcastle.codeplex.com/]]や[[NDoc:http://ndoc.sourceforge.net/]]などいくつか種類がありますが、ここでは一つの例としてコマンドラインでのドキュメント生成が行える[[Monodoc:http://www.mono-project.com/Monodoc]]を使ってHTMLに変換する例を紹介します。 Monodocはドキュメントの編集と閲覧を行うためのツールですが、コンパイラが生成するXMLドキュメントをインポートしてHTML形式に整形して出力させることも出来るようになっています。
XMLドキュメントを整形したり他の形式に変換するツールにはいくつか種類がありますが、ここでは一つの例として[[Monodoc:http://www.mono-project.com/Monodoc]]を使ってHTMLに変換する例を紹介します。 Monodocはドキュメントの編集と閲覧を行うためのツールですが、コンパイラが生成するXMLドキュメントをインポートしてHTML形式に整形して出力させることも出来るようになっています。
 

        

        
 
ではMonodocを使ってXMLドキュメントからHTMLを作成する手順について見ていきます。 ここでは[[programming/netfx/classlibrary/0_howtocreate]]で作成したライブラリSmdn.Utils.dllを使ってHTMLを作成します。 ビルドが完了した時点でのディレクトリ構成は次のようになっています。
ではMonodocを使ってXMLドキュメントからHTMLを作成する手順について見ていきます。 ここでは[[programming/netfx/classlibrary/0_howtocreate]]で作成したライブラリSmdn.Utils.dllを使ってHTMLを作成します。 ビルドが完了した時点でのディレクトリ構成は次のようになっています。
 

        

        
624,246 419,5
 

        

        
 
#image(monodoc-00.png,60%,Monodocによって生成されたHTML)
#image(monodoc-00.png,60%,Monodocによって生成されたHTML)
 

        

        
+
*XMLドキュメントと翻訳
+
[[コンパイラやオブジェクトブラウザが認識するXMLドキュメントの要素>#document_elements]]にはドキュメントの言語に関する規定がなく、日本語や英語など複数の言語でドキュメントを記述する方法については特にこれといった方法が用意されていません。 そのため、複数の言語でドキュメントを記述したり、ローカライズされたドキュメントを生成するには何らかの追加的な手順をとる必要があります。
+

          
+
**条件付きコンパイルを使う方法
+
#ifディレクティブによる条件付きコンパイルはXMLドキュメントコメント部にも適用されます。 そこで、各言語毎にXMLドキュメントコメントを記述し、言語別のドキュメントを生成するシンボルを定義することで出力されるXMLドキュメントの言語を切り替えるようにすることができます。
+

          
+
次の例では、シンボル``DOCLANG_JA``が定義されている場合は日本語、それ以外はデフォルトとして英語のドキュメントが生成されるようにXMLドキュメントコメントを記述しています。
+

          
+
#code(cs,条件付きコンパイルで言語別のXMLドキュメントを生成する例){{
+
using System;
+

          
+
namespace Smdn.Utils
+
{
+
#if DOCLANG_JA
+
  /// <summary>文字列操作に関するユーティリティメソッドを提供するクラスです。</summary>
+
#else
+
  /// <summary>The StringUtils class provides string-related utility methods.</summary>
+
#endif
+
  public static class StringUtils
+
  {
+
  }
+
}
+
}}
+

          
+
このように記述されたソースコードを、シンボルの定義なしでコンパイルすれば英語のドキュメントが生成されます。
+

          
+
#prompt{{
+
csc StringUtils.cs /out:Smdn.Utils.dll /target:library /doc:Smdn.Utils.xml
+
}}
+

          
+
#code(xml,生成されるXMLドキュメント){{
+
<?xml version="1.0"?>
+
<doc>
+
    <assembly>
+
        <name>Smdn.Utils</name>
+
    </assembly>
+
    <members>
+
        <member name="T:Smdn.Utils.StringUtils">
+
            <summary>The StringUtils class provides string-related utility methods.</summary>
+
        </member>
+
    </members>
+
</doc>
+
}}
+

          
+
そして、/defineスイッチでシンボル``DOCLANG_JA``を定義してコンパイルすれば日本語のドキュメントが生成されます。
+

          
+
#prompt{{
+
csc StringUtils.cs /out:Smdn.Utils.dll /target:library /define:DOCLANG_JA /doc:Smdn.Utils.xml
+
}}
+

          
+
#code(xml,生成されるXMLドキュメント){{
+
<?xml version="1.0"?>
+
<doc>
+
    <assembly>
+
        <name>Smdn.Utils</name>
+
    </assembly>
+
    <members>
+
        <member name="T:Smdn.Utils.StringUtils">
+
            <summary>文字列操作に関するユーティリティメソッドを提供するクラスです。</summary>
+
        </member>
+
    </members>
+
</doc>
+
}}
+

          
+
この方法ではシンボルの定義だけで言語別のドキュメントを生成できるという利点がありますが、記述しなければならない言語の数が増えれば#ifディレクティブによる分岐が煩雑になり、また言語の数だけコンパイルを行う必要があるという欠点があります。
+

          
+
**独自の要素・属性を使う方法
+
XMLドキュメントコメントでは[[独自の要素や属性>#document_extension]]を使うことができるため、これを使って言語別にマークアップを行うことができます。 ここでは例として、使用が推奨される要素にxml:lang属性を付加して言語別にドキュメントコメントを記述することにします。 なお、xml:lang属性がないものはドキュメントにおけるデフォルトの言語(未翻訳のドキュメント)であるとします。
+

          
+
#code(cs,xml:lang属性を付加して言語別のXMLドキュメントコメントを記述する例){{
+
using System;
+

          
+
namespace Smdn.Utils
+
{
+
  /// <summary xml:lang="ja">文字列操作に関するユーティリティメソッドを提供するクラスです。</summary>
+
  /// <summary>The StringUtils class provides string-related utility methods.</summary>
+
  public static class StringUtils
+
  {
+
    /// <summary>The Method1</summary>
+
    /// <summary xml:lang="ja">メソッド1</summary>
+
    public static void Method1()
+
    {
+
    }
+

          
+
    /// <summary>The Method2</summary>
+
    public static void Method2()
+
    {
+
    }
+
  }
+
}
+
}}
+

          
+
このように記述されたソースコードをコンパイルすると次のようなドキュメントが生成されます。
+

          
+
#code(xml,生成されるドキュメント){{
+
<?xml version="1.0"?>
+
<doc>
+
    <assembly>
+
        <name>Smdn.Utils</name>
+
    </assembly>
+
    <members>
+
        <member name="T:Smdn.Utils.StringUtils">
+
            <summary xml:lang="ja">文字列操作に関するユーティリティメソッドを提供するクラスです。</summary>
+
            <summary>The StringUtils class provides string-related utility methods.</summary>
+
        </member>
+
        <member name="M:Smdn.Utils.StringUtils.Method1">
+
            <summary>The Method1</summary>
+
            <summary xml:lang="ja">メソッド1</summary>
+
        </member>
+
        <member name="M:Smdn.Utils.StringUtils.Method2">
+
            <summary>The Method2</summary>
+
        </member>
+
    </members>
+
</doc>
+
}}
+

          
+
このままでは複数の言語での記述が混在したままとなるので、xml:lang属性に指定されている値を使って目的の言語だけの記述となるようにフィルタリングします。 ここでは次のような簡易ツールを使ってフィルタリングを行います。
+

          
+
#code(cs,xml:lang属性の値に従ってXMLドキュメントの要素をフィルタリングする簡易ツール){{
+
using System;
+
using System.Collections.Generic;
+
using System.Xml;
+

          
+
public class XmlLangFilter
+
{
+
  public static void Main(string[] args)
+
  {
+
    // 第一引数で与えられたXMLファイルを読み込む
+
    var document = new XmlDocument();
+

          
+
    document.Load(args[0]);
+

          
+
    // 第二引数で与えられるxml:langの値にしたがって要素をフィルタリングする
+
    var filterLang = 2 <= args.Length ? args[1] : string.Empty;
+

          
+
    // 全ての/doc/members/member要素について、引数で与えられたxml:langの値を持つ要素だけをフィルタリングする
+
    foreach (XmlElement memberElement in document.SelectNodes("/doc/members/member")) {
+
      // member下の要素名と要素のXmlElementを格納するDictionary
+
      var langElement = new Dictionary<string, XmlElement>();
+
      // member下の全てのXmlElementを格納するList
+
      var elements = new List<XmlElement>();
+

          
+
      // menber要素のすべての子要素を列挙
+
      foreach (XmlElement element in memberElement.ChildNodes) {
+
        elements.Add(element);
+

          
+
        // 要素名を取得
+
        var name = element.Name;
+
        // xml:lang属性の値を取得
+
        var lang = element.GetAttribute("xml:lang");
+

          
+
        // xml:lang属性を削除する
+
        element.RemoveAttribute("xml:lang");
+

          
+
        if (langElement.ContainsKey(name)) {
+
          // すでにDictionaryに同名の要素が格納されている場合、
+
          // xml:langが目的の値を持つ場合に限り上書きする
+
          if (lang == filterLang)
+
            langElement[name] = element;
+
        }
+
        else {
+
          langElement[name] = element;
+
        }
+
      }
+

          
+
      // 一旦member要素のすべての子要素を削除する
+
      foreach (var element in elements) {
+
        memberElement.RemoveChild(element);
+
      }
+

          
+
      // フィルタリングした要素だけを追加する
+
      foreach (var element in langElement.Values) {
+
        memberElement.AppendChild(element);
+
      }
+
    }
+

          
+
    // フィルタリングしたXMLドキュメントを標準出力に書き出す
+
    var writerSettings = new XmlWriterSettings();
+

          
+
    writerSettings.Indent = true;
+
    writerSettings.IndentChars = "    ";
+

          
+
    var writer = XmlWriter.Create(Console.OpenStandardOutput(), writerSettings);
+

          
+
    document.Save(writer);
+
  }
+
}
+
}}
+

          
+
このツールを使ってフィルタリングすることにより、次のように言語別のドキュメントを得ることができます。
+

          
+
#prompt{{
+
XmlLangFilter.exe input.xml
+
}}
+

          
+
#code(xml,xml:lang属性の指定されていない要素だけをフィルタリングした結果){{
+
<?xml version="1.0"?>
+
<doc>
+
    <assembly>
+
        <name>Smdn.Utils</name>
+
    </assembly>
+
    <members>
+
        <member name="T:Smdn.Utils.StringUtils">
+
            <summary>The StringUtils class provides string-related utility methods.</summary>
+
        </member>
+
        <member name="M:Smdn.Utils.StringUtils.Method1">
+
            <summary>The Method1</summary>
+
        </member>
+
        <member name="M:Smdn.Utils.StringUtils.Method2">
+
            <summary>The Method2</summary>
+
        </member>
+
    </members>
+
</doc>
+
}}
+

          
+
#prompt{{
+
XmlLangFilter.exe input.xml ja
+
}}
+

          
+
#code(xml,xml:lang属性にjaが指定されている要素だけをフィルタリングした結果){{
+
<?xml version="1.0"?>
+
<doc>
+
    <assembly>
+
        <name>Smdn.Utils</name>
+
    </assembly>
+
    <members>
+
        <member name="T:Smdn.Utils.StringUtils">
+
            <summary>文字列操作に関するユーティリティメソッドを提供するクラスです。</summary>
+
        </member>
+
        <member name="M:Smdn.Utils.StringUtils.Method1">
+
            <summary>メソッド1</summary>
+
        </member>
+
        <member name="M:Smdn.Utils.StringUtils.Method2">
+
            <summary>The Method2</summary>
+
        </member>
+
    </members>
+
</doc>
+
}}
+

          
+
この方法では属性を付け加えるだけで言語別のドキュメントを記述でき、また記述されている言語の数に関わらずドキュメントの生成には一度だけのコンパイルで済むという利点がありますが、生成したドキュメントに対して加工を行うツールが必要になり、ドキュメントの加工を行う手順が増えるという欠点があります。
+

          
 
#navi(..)
#navi(..)