ドキュメンテーションコメントとは
ドキュメンテーションコメントは、 よく型定義やメンバなどの直前に書かれるコメントで、 その型やメンバの仕様を説明するものである。 ここで重要なのが、 「実装」ではなく「仕様」の説明であるということだ。
基本的には、その型やメンバの「利用者」に向けた仕様説明だと思った方がよい。 「実装者」に向けた説明ではないのだ。 もちろん実装者がその実装の過程で、 ドキュメンテーションコメントを参考にすることもあるだろう。 しかしそれは「このメソッドってどういう仕様だっけ」というような、 仕様を確認するために見るぐらいだろう。
外から見えないもので説明しない
前述のように、ドキュメンテーションコメントは 利用者に向けた仕様説明である。 そのため、実装者しか見えないプライベートな要素を使って 説明するのはよろしくない。
例えば、private
なメンバの名前や、
ローカル変数の名前が、説明文中に登場するのはよろしくない。
例1
private bool hasValue = false; /// <summary> /// hasValue が true の場合に名前を返す。 /// false の場合は空文字列を返す。 /// </summary> public string Name => hasValue ? name : string.Empty;
hasValue
というフラグ名が説明文中に登場する。
どうやら、hasValue
というフラグによって振る舞いが変わるようだが、
そのフラグは外部からは見えず、
利用者にとっては謎のフラグだ。
利用者に見せている要素のみで説明すると、 例えば下記のようになる。
/// <summary> /// コンストラクタで名前が与えられていればその名前を返す。 /// そうでなければ空文字列を返す。 /// </summary> public string Name => hasValue ? name : string.Empty;
あるいは、そのフラグを外部に見せてしまうという手もある。 その場合、フラグにもドキュメンテーションコメントを記載し、 true や false になる条件を書こう。
/// <summary> /// コンストラクタで名前が与えられていれば true、 /// そうでなければ false。 /// </summary> public bool HasValue { get; } = false; /// <summary> /// <see cref="HasValue"/> が true の場合に名前を返す。 /// false の場合は空文字列を返す。 /// </summary> public string Name => hasValue ? name : string.Empty;
例2
private const int userNumMax = 999; /// <summary> /// 新しくユーザーを追加する。 /// </summary> /// <exception cref="InvalidOperationException"> /// すでに userNumMax 人登録されている場合。 /// </exception> public void AddUser(User newUser) { // ... }
どうやらこのクラスには、登録できるユーザ数に上限があって、
それを超えると例外を発生させるようだ。
ただ、userNumMax
が外部から見えないので、
利用者は何人なら登録できるのか分からない。
上限人数が分かるように、
/// <exception cref="InvalidOperationException"> /// すでに 999 人登録されている場合。 /// </exception>
のように書いてもいいが、それだと「999」という数字を コード中の 2 カ所に書くことになり、DRY の原則に反する。 さっきよりマシではあるが。
なので、上限人数を利用者が見えるようにしよう。
/// <summary>登録できる上限人数</summary> public int UserNumMax => 999; /// <summary> /// 新しくユーザーを追加する。 /// </summary> /// <exception cref="InvalidOperationException"> /// すでに <see cref="UserNumMax"/> 人登録されている場合。 /// </exception> public void AddUser(User newUser) { // ... }
余談だが、上限人数を外部に見せることはなにかと便利である。 例えば、ユーザーが見る画面に「最大○人まで登録できます。」というような 文言を表示するのにも使える。
例3
private readonly System.Timers.Timer timer = new System.Timers.Timer(1000); /// <summary> /// バックグラウンドで定期処理を開始する /// </summary> /// <exception cref="InvalidOperationException">タイマーが既に実行中の場合</exception> public void StartPolling() { // ... }
このメソッドは、定期処理をタイマー (System.Timers.Timer) を使って実現している。
具体的なメンバ名 (timer
) こそ出ていないものの、
「タイマー」という語は利用者にとっては初出だし、何のことか分からないかもしれない。
また、タイマーを使っているのは内部の事情であり、利用者にとっては関係のないことである。 定期処理を、タイマーで実現しようが無限ループで実現しようが、 利用者にとってはブラックボックスだ。
内部の要素を使わずに説明するとなると、 例えば、下記のようにするとよいだろう。
/// <exception cref="InvalidOperationException">定期処理が既に開始されている場合</exception>