マネージド コードの確認

 

John D'Addamio
Microsoft Corporation

2007 年 2 月

適用対象:
   .NET Framework

概要: このドキュメントでは、マネージド コードを確認するためのベスト プラクティスについて説明します。 一部のプラクティスは、マネージド コードとアンマネージド コードを確認するための汎用的な方法です。 その他のコードは、マネージド コードのレビューに固有です。 少なくとも 1 つのマネージド言語に精通していることを前提としていますが、マネージド コードの経験豊富なレビュー担当者であるという前提はありません。 (6ページ印刷)

内容

はじめに
推奨される関連ガイドライン
推奨される操作
まとめ

はじめに

マネージド コードのレビューは、アンマネージド コードのレビューとは少し異なります。 いくつかの点で、マネージド コードの確認は、他のコードを確認するよりも簡単です。 コンパイラは型をチェックし、互換性のないデータをオブジェクトに誤って割り当てないようにします。 コンパイラは、初期化されていない変数の使用も確認します。 これらのコンパイル チェックやその他のコンパイル チェックにより、コード レビューの実行時に以前に探さなければならないバグのホスト全体が防止されます。 さらに、ランタイム チェックでは、他の一般的な問題を検出し、例外をスローすることで損害が含まれます。 他の方法では、マネージド コードによって、ソース ファイル自体のリソース ファイルや XML 要素など、他の言語に存在しない問題がいくつか追加されます。

このドキュメントでは、マネージド コードを確認するためのベスト プラクティスについて説明します。 C# や Visual Basic.NET など、少なくとも 1 つのマネージド言語に精通していることを前提としていますが、マネージ コードの経験豊富なレビュー担当者であるという前提はありません。

MSDN には多くの関連ガイドラインがあります。 多くは設計ガイドラインとして意図されていますが、コード レビューにも明らかに適用されます。 いくつかの例を次に示します。

  1. .NET 設計ガイドライン
  2. 名前付けのガイドライン
  3. キャストの種類に関するガイドライン

FxCop を使用してコーディング標準を適用する

FxCop は、先ほど参照した .NET デザイン ガイドラインに準拠しているかどうかを .NET マネージ コード アセンブリをチェックするコード分析ツールです。 FxCop には標準のコード分析ルールが用意されており、プロジェクトのルールをカスタマイズできます。 FxCop 警告の抑制は、ソース コードでも許可されます。 FxCop チーム ページから、詳細を取得したり、 FxCop とそのドキュメントを無料でダウンロードしたりできます。

レビュー中のコードに対して FxCop を実行する

各プロジェクトで実装する必要がある FxCop コード分析を実行する標準ビルド構成を定義します。 コード レビューの一環として、プロジェクトが標準の FxCop ビルド構成を正しく実装していること、およびレビュー対象のコードが FxCop 構成をビルドすることによって FxCop 評価に合格することを確認します。

ソース コードでの FxCop エラーの抑制の確認

FxCop メッセージの抑制を確認するコードを検索します。 Ctrl + F キーを押して、現在のプロジェクトで "SuppressMessage" を検索できます。 FxCop 抑制が見つかる場合は、それらが正当に必要であり、抑制の理由がコメントで明確に説明されていることを確認します。 場合によっては、抑制は必要ありませんが、コードを記述するユーザーがエラーを修正する方法を知らなかった場合があります。 たとえば、次の抑制は不要です。

// FxCop doesn't like the "\n\n" so we suppress the error message here.
[System.Diagnostics.CodeAnalysis.SuppressMessage
("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = 
"System.Windows.Forms.TextBoxBase.AppendText(System.String)")]
this.resultsTextBox.AppendText ("\n\n" + Strings.contextErrorMessage);

コードを簡単に変更すると、FxCop エラーが発生するのを防ぐことができます。

this.resultsTextBox.AppendText( Environment.NewLine + 
Environment.NewLine + Strings.contextErrorMessage);

ロジックの確認

もちろん、コードをレビューするメインポイントは、ロジック (バグ) の欠陥を探し、チームのコーディング標準を適用することです。 FxCop を使用してコーディング標準を適用すると、コードのロジックの確認により多くの時間を費やすことができます。

.NET Frameworkには多くのクラスがあり、各クラスには多くのメソッドがあります。 そのため、クラスまたはメソッドに対して IntelliSense の説明を自由に使用してください。

既存のコメントと、クラスまたはメソッドの IntelliSense の説明からコードが何を行うかを理解できない場合、コードには十分なコメントがありません。 ロジックが作成者が主張する処理を行わないと思われる場合は、ロジックに欠陥があるか、コードに明確にするための十分なコメントがありません。

ビルド

プロジェクトのすべての構成でコードをビルドすることをお勧めします。 作成者は、すべての構成でビルドを忘れた可能性があります。 すべての構成でビルドされない場合は、コードを送信する前に、作成者にエラーの修正を要求する必要があります。

たとえば、単体テストを除外するリリース構成を定義するのが一般的です。 メソッドのシグネチャに変更が加えられたが、単体テストが更新されない場合、コードは Release 構成では正常にビルドされますが、デバッグ構成ではビルドされません。

単体テストの検索

新しいコードを確認するときは、機能コードと同時に単体テストが表示されることを想定します。 先延ばしにするのは簡単すぎる!

コードの変更を確認する場合は、新しい単体テストまたは改訂された単体テストが必要になる場合があります。 コード レビューで送信された既存の単体テストとを実行します。 単体テストに合格しない場合は、作成者に機能コードや単体テストを更新して、合格するように要求します。

パラメーターの検証の検索

メソッドで入力パラメーターを検証することをお勧めします。 パラメーターが無効な場合、メソッドは適切なアクションを実行する必要があります。 たとえば、文字列パラメーターが null オブジェクトであるか、 String.Empty と等しいかどうかを確認する必要があります。 String.IsNullOrEmptytrue を返す状況で適切なアクションは、例外 (ArgumentException や ArgumentNullException など) をスローすることですが、別の状況では、メソッドはアクションを実行せずに呼び出し元に戻るだけの場合があります。

コードを確認するときは、望ましくない動作を引き起こす可能性のあるパラメーター値を探します。 "bad" 値は、示されている文字列の例と同じくらい明白ですが、オーバートが少ない可能性があります。 たとえば、0.0 ~ 100.0 の数値データを表す文字列を考えてみましょう。 コードでは、先頭と末尾の空白のトリミング、文字列を数値形式に変換する、値が想定される範囲内にあることを検証するなど、null チェックに加えて検証を行う必要がある場合があります。

説明

必要な XML 要素

各クラス定義とすべてのパブリック メンバーには、クラスまたはメンバーを記述するための XML サマリー タグが必要です。 これにより、 クラスのユーザーは、コードを編集するときに説明を表示できます。 XML パラメーター タグが適用される場合は、XML パラメーター タグも必要です。 Visual Studio 2005 では、クラスまたはメソッド定義の上の空白行に /// と ''' (それぞれ) と入力すると、C# と Visual Basic のコード エディターによって サマリー タグと パラメーター タグが自動的に挿入されます。 XML タグ定義を正しく入力する必要がないため、これは非常に便利です。 説明を入力するだけで済みます。

チームがクラスまたはメンバー定義に対してより複雑な XML ヘッダーを使用している場合 (たとえば、一部のチームでは、変更履歴 (変更、作成者、日付情報の説明など) を記述する XML ヘッダーが必要です)、ヘッダーが存在し、適切なデータが入力されていることを確認します。

すべての XML 要素を検証する

すべての XML 要素が整形式であることを確認します。 ソース コードで XML コメントを処理するツールでは、正しく機能するために整形式の XML が必要であるため、これは重要です。

自動生成された XML 要素がチームに必要ない場合は、空の XML 要素をすべて削除します。 たとえば、Visual Basic では、多くの場合に削除できる 戻り 値と 注釈 要素が自動生成されます。

その他のコメント

コード要素の使用、ロジック、または動作を説明するのに十分な追加のコメントがコードにあることを確認します。

コメントの品質

コメントは、関連するコードを明確かつ正確に記述する必要があります。 コメントがコードと一致しない一般的な状況がいくつかあります。 彼らを見てください! たとえば、モジュールで既存のコードが変更された場合、コメントの更新が見落とされることがあります。 または、別のアプリケーションのコードセクションが現在の目的に適合している場合、元のコードからのコメントが適切または正確でなくなる可能性があります。

文字列定数

文字列リソース ファイル

文字列リテラルは、文字列リソース ファイルにパッケージ化する必要があります。 これにより、文字列が 1 か所に収集されるため、文字列テキストの変更が容易になります。 文字列リソース ファイルを使用すると、ローカライズとグローバリゼーションも可能になります。 文字列リソース ファイルの作成と使用は、以前は中程度に面倒でした。 ただし、 リソースリファクタリング ツール は、少なくとも C# および Visual Basic プロジェクトの場合、この問題に役立ちます。 たとえば、次のステートメントの文字列リテラルです。

private static string snippetSchemaPathBegin = 
Path.Combine(Environment.ExpandEnvironmentVariables("%ProgramFiles%"), 
@"\Microsoft Visual Studio 8\Xml\Schemas");

リソース リファクタリング ツールを使用すると、すぐに次のように変更できます。

private static string snippetSchemaPathBegin = 
Path.Combine(Environment.ExpandEnvironmentVariables( 
Strings.ProgramFiles), Strings.MicrosoftVisualStudio8XmlSchemas);

ファイル名とパス

コードを確認するときは、ハードコーディングされたファイル パスを含む文字列リテラルまたは文字列リソース ファイル参照を探します。 環境変数、パス名を指定する .NET API (アプリケーションを起動した実行可能ファイルのパスを返す System.Windows.Forms.Application.ExecutablePath など)、または参照パスへの構成ファイル エントリを常に使用します。 People頻繁に C 以外のドライブにインストールし、場合によっては他の方法でインストール場所をカスタマイズします。

同様に、アプリケーションのファイル名は、文字列リテラルまたは文字列リソース ファイル参照で定義しないでください。 代わりに、構成ファイル、環境変数、またはユーザーからの入力 (コンソール アプリケーションへのパラメーターや WinForms アプリケーションのファイル ダイアログ ボックスなど) を使用できます。 これらの代替手段を使用すると、ユーザーはアプリケーションをより柔軟に使用できます。

次の例は、ハードコーディングされたパスやパブリック変数など、いくつかの不適切なプラクティスを示しています。

     public static readonly string SnippetSchemaPathBegin = 
@"C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas\";

ステートメントは、次に示すように、パブリック プロパティと SystemDrive 環境変数を使用して書き換えることができます。

        public string SnippetSchemaPathBegin { get { return 
snippetSchemaPathBegin; } }
        private static string snippetSchemaPathBegin = 
Environment.ExpandEnvironmentVariables("%SystemDrive%" + @"\Program 
Files\Microsoft Visual Studio 8\Xml\Schemas");

同様に、次に示すように、ProgramFiles 環境変数を使用することもできます。

        private static string snippetSchemaPathBegin = 
Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles"), 
@"Microsoft Visual Studio 8\Xml\Schemas");

命名規則

名前

一般に、名前は読み取り可能で、項目を明確に記述する必要があります。 そのため、コード レビューを実行するときに、名前、短い名前、またはわかりやすい名前の省略形を探します。 関数名とメソッド名を動詞で始め、オブジェクトに対して実行するアクションを示すのが良い方法です。 同様に、変数名とプロパティ名はオブジェクトであるため、名詞にする必要があります。 たとえば、円などの平面ジオメトリ オブジェクトのクラスを作成する場合は、 CenterPointRadius という名前のプロパティを定義できます。 このようなクラスの関数名には、 CalculateCircumferenceCalculateArea が含まれる場合があります。

名前の大文字と小文字の表記規則

ソース コードが、前に推奨された名前付けガイドラインのドキュメントの 「大文字と小文字の区別のスタイル 」セクションで推奨されている大文字と小文字の表記規則に従っていることを確認します。 つまり、パラメーター、ローカル変数、およびクラスのプライベート変数または保護された変数には、 camelCasing (名前の最初の文字は小文字、名前の後続の各単語の最初の文字は大文字) を使用します。 クラス名、メソッド、プロパティ、型宣言、列挙型の値など、他のほとんどすべての場合は、 PascalCasing (名前の各単語の最初の文字は大文字) を使用します。

ハンガリー記法

マネージ コードではハンガリー語表記は推奨されません。 ハンガリー語表記は正しく使用するのが難しいだけでなく、読みにくいです。 ハンガリー語表記を読むのが難しいと、ロジックを難読化することもできます。

例外

例外のスロー

コードが例外をスローする場合は、例外の種類が適切であり、コードが例外をスローする原因となった問題がメッセージによって明確に識別されていることを確認します。 可能な限り多くのデバッグ情報を例外メッセージに格納します。 これは、スタック トレースまたはログ ファイルのいずれから問題を診断する場合に役立ちます。

例外のキャッチ

確認しているコードが、例外をスローする可能性が高いメソッドを呼び出す場合は、コードが例外を処理し、それを処理するときに妥当な処理を行うことを確認します。 たとえば、 File.Open では、 FileNotFoundExceptionUnauthorizedAccessException など、いくつかの一般的な例外がスローされます。 これらの例外をキャッチし、ユーザーにエラー メッセージを表示するのが妥当です。

例外の定義

アセンブリのコードで例外が定義されている場合は、アセンブリのグローバル例外クラスで一般的に使用される型を定義します。 クラス自体のクラスに固有の例外を定義します。

書式設定

領域を使用してコードを整理する

コードを確認するときは、コードの読みやすさを向上させるためにリージョンを適切に使用することを確認します。 多くの場合、リージョンは使い過ぎですが、使い過ぎることがあります。

不要な領域を折りたたんで、現在必要なコードの部分のみを表示できるため、リージョンはコードを論理的に整理し、大きなファイルの読みやすさを向上させるのに役立ちます。 また、領域を折りたたみると、大きなファイルをスクロールして目的の領域を見つけることもできます。 ただし、入れ子になったリージョンの使用方法には注意してください。 外側の領域を折りたたむと、内側の領域が非表示になり、実際には関心のある領域を見つけるのが難しくなる可能性があります。

リージョンを使用する一般的な場所には、クラスのプライベート データ、コンストラクター、パブリック プロパティ、プライベート メソッド、パブリック メソッドなどがあります。 テスト プロジェクトでは、テストをグループ化するためにリージョンが一般的に使用されます。 たとえば、リージョンでは、クラスのいずれかのメソッドの単体テストをグループ化できます。

空白行を使用して定義を区切る

同じレベルの定義間に空白行を使用すると、読みやすさが向上します。 ただし、連続する空白行は 2 行を超えないでください。

その他

パブリック変数なし

クラスのデータ変数がプライベートとして宣言されていることを確認します。 データへのアクセスを許可する場合は、パブリックまたは保護されたプロパティを定義して、ユーザーにアクセス権を付与します。

戻り値

値を返すメソッドでは、メソッド名に値を割り当てる代わりに、return ステートメントを使用する必要があります。

GoTo ステートメントなし

GoTo ステートメントは不要です。 特別な状況で使用するケースを作成することがありますが、コード レビューでアラームが表示されたらアラームをオフにする必要があります。

数値定数

ほぼすべてのデバッグ ツールでは、既定で数値定数が 16 進数で表示されます。 したがって、デバッグ中に 10 進数から 16 進数に変換する必要がないように、ウィンドウ ID、コントロール ID などの数値定数を 16 進数で定義します。

まとめ

このドキュメントでは、マネージド コードを確認するためのベスト プラクティスについて説明しました。 一部のプラクティスは、マネージド コードとアンマネージド コードを確認するための普遍的な方法です。 その他のコードは、マネージド コードのレビューに固有です。