Silverlight をインストールするには、ここをクリックします*
Japan変更|すべてのMicrosoft のサイト|サインイン
MSDN*
マイクロソフト サイトの検索:
|MSDN ライブラリ|デベロッパー センター|ダウンロード情報|開発ツール製品|コミュニティ|ご意見・ご要望|サイトマップ
MSDN Home > ステップ 7 > Visual Studio 2005 Team System によるアプリケーション品質の向上 > その 1 - 静的コード分析の設定と実施

ステップ 7 ハンズオン 「Visual Studio 2005 Team System によるアプリケーション品質の向上」

第 2 回 品質の高いコード作成 (1) - その 1

静的コード分析の設定と実施

NRIラーニングネットワーク
荒木 達也

最終更新日 2007 年 10 月 10 日

目標 Visual Studio Team System を利用した高品質コードの作成
使用技術
  • Visual Studio Team System / C#
  • .NET Framework 2.0
取り上げるトピックス
  • 静的コード分析
前提知識
関連記事  

静的コード分析

今回は、引数として渡される商品コードをもとに SQL (SELECTステートメント) を発行し、該当する商品名を結果として返す ”GetProductName” メソッドを、コード分析の対象とします。
(このプログラムは、Step1 で作成します)

図1.コード分析するサンプルコンポーネント

実装する処理 メソッド 呼び出し対象
商品名取得 GetProductName  

なお、今回コード分析する規則 (CODE_ANALYSIS定数) は以下の通りです。

規則名 詳細の規則
セキュリティ規則 すべて
パフォーマンス規則 すべて
信頼性の規則 すべて

Visual Studio 2005 を起動し、メニューより [ ファイル ] - [ 新規作成 ] - [ プロジェクト ] の順に選択し、新しいプロジェクトを作成します。

プロジェクトの種類 テンプレート プロジェクト名
C# - Windows クラス ライブラリ MyLibs

図2. プロジェクト ”MyLibs”" の作成

作成したプロジェクトの既定のクラス ”Class1” を ”MyComp1” に変名し、データベースへ商品名を問い合わせる ”GetProductName” メソッドを作成します。

public String GetProductName(int productId)
{
    String result;
    SqlConnection cn = new SqlConnection(constr);
    SqlCommand cmd = new SqlCommand();

    cmd.Connection = cn;
    cmd.CommandText = "SELECT ProductName FROM Products" +
        " WHERE ProductID = " + productId.ToString();
    try
    {
        cn.Open();
        result = (String)cmd.ExecuteScalar();

        cn.Close();
        cmd.Dispose();
        cn.Dispose();
    }
    catch
    {
        result = "";
    }
    return (result);
}

プログラム記述後、既定の環境 (静的なコードが無効な状態) でビルドします。

メニューより [ ビルド ] - [ MyLibs のビルド ] を選択します。

ビルドの結果が表示され、正常にコンパイルされた旨通知されます。

図3. ビルド結果

静的コード分析を有効にします。

メニューより [ プロジェクト ] - [ MyLibs のプロパティ ] を選択します。

[ MyLibs ] プロジェクトプロパティ のダイアログにて、[ コード分析 ] タブを選択後、

  • ”コード分析の有効化 (CODE_ANALYSIS 定数を定義)”
  • ”セキュリティ規則”
  • ”パフォーマンス規則”
  • ”信頼性の規則”

の 4 つのチェックボックスを ”ON” にします。

図4. コード分析の有効化

静的なコード分析が有効な状態でビルドします。

メニューより [ ビルド ] - [ MyLibs のビルド ] を選択します。

ビルドの結果が表示され、正常にコンパイルされた旨通知されます。

図5.ビルド結果

コンパイルの結果と共に、コード分析の結果も表示されます。

詳細を確認するには、メニューより [ 表示 ] - [ エラー一覧 ] を選択します。

図6.コード分析の結果

分析の結果、以下の 4 か所について警告を受けていることが分ります。

  • ”信頼性の規則” で 2 か所
    変数 cmd と変数 cn の後処理 (オブジェクトの破棄) が行われてません。特に cn については、try ブロックの中で、後処理に相当する Close メソッドを呼び出していますが、この呼び出しの前に例外が発生すると、catch ブロックに制御が移ってしまい、後処理ができません。 このコードには、後処理が行われない処理フロー (コードパス) が存在しています。

  • ”パフォーマンス規則” で 1 か所
    非 static メソッドよりも、static メソッド (静的メソッド) のほうが、内部的なパラメータが一つ少なく負荷が減ります。static メソッドで済む場合には、static メソッドを使用するようにします。

  • ”セキュリティ規則” で 1 か所
    SQLインジェクションの危険性があります。つまり、SQL 文の文字列の WHERE 句の後に、不適切なコマンド文字列を連結して、不正な操作をさせる可能性があります。WHERE 句の後ろの抽出条件は、単純な文字列連結ではなく、パラメータ化するなど、特定の項目しか代入できないようにします。

警告を受けたコードを修正します。

public static String GetProductName(int productId)
{
    String result;
SqlConnection cn = new SqlConnection(constr);
    SqlCommand cmd = new SqlCommand();
    
cmd.Connection = cn;
    cmd.CommandText = "SELECT ProductName FROM Products" +
        " WHERE ProductID = @ProductID";
    SqlParameter parmProdID = cmd.Parameters.Add
        ("@ProductID",SqlDbType.Int);
    parmProdID.Value = productId;
    try
    {
        cn.Open();
        result = (String)cmd.ExecuteScalar();
    }
    catch
    {
        result = "";
    }
    finally
    {
        cn.Close();
        cmd.Dispose();
        cn.Dispose();
    }
    return (result);
}

修正は、以下の 4 か所です。

  • コネクション、コマンドオブジェクトの確実な破棄 (2か所)
    例外処理に finally ブロックを追加し、例外発生の有無に関わらず、確実にコネクション、コマンドオブジェクトを破棄します。

  • メソッドの static 化
    つまり、静的メソッドにします。

  • SQL ステートメントのパラメータ化
    WHERE 句の抽出条件をパラメータ化し、整数のみ受け渡せるようにします。

もう一度、静的なコード分析が有効な状態でビルドします。

メニューより [ ビルド ] - [ MyLibs のビルド ] を選択します。

ビルドの結果が表示され、正常にコンパイルされた旨通知されます。

図7.ビルド結果

コンパイルの結果と共に、コード分析の結果も表示されます。

コード修正後の分析結果は良好 (警告は ”0 (ゼロ)”) です。

このプログラムに対するコード分析は完了したので、静的なコード分析は “無効” に戻しておきます。

メニューより [ プロジェクト ] - [ MyLibs のプロパティ ] を選択します。

[ MyLibs ] プロジェクトプロパティ のダイアログにて、[ コード分析 ] タブを選択後、

  • ”コード分析の有効化 (CODE_ANALYSIS 定数を定義)”

のチェックボックスを ”OFF”にします。

次に、「その 2 : プロファイリング 」 について説明します。


Top of Page Top of Page

Microsoft