3

プロジェクトにコードのセクションがあり、使用ブロックを別の使用ブロックの内側にラップしています。これは良い習慣なのか、それともやり過ぎなのか疑問に思います(これは非常に単純なコードのスニペットであることに注意してください。説明のみを目的として使用):

protected void Submit_Click(object sender, EventArgs e)
    {
        try
        {
            using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegConnectionString"].ConnectionString))
            {
                cn.Open();

                string cmdStr = "SELECT COUNT(*) FROM REGISTRATION WHERE UserName ='" + this.TextBoxUN.Text + "' ";
                using (SqlCommand selectUser = new SqlCommand(cmdStr, cn))
                {
                    int temp = Convert.ToInt32(selectUser.ExecuteScalar().ToString());

                    if (temp == 0)
                    {
                        string insCmd = "Insert INTO REGISTRATION (UserName, Password, EmailAddress, FullName, Country) VALUES (@UserName, @Password, @EmailAddress, @FullName, @Country)";
                        using (SqlCommand insertUser = new SqlCommand(insCmd, cn))
                        {
                            try
                            {
                                insertUser.Parameters.AddWithValue("@UserName", this.TextBoxUN.Text);
                                insertUser.Parameters.AddWithValue("@Password", this.TextBoxPass.Text);
                                insertUser.Parameters.AddWithValue("@EmailAddress", this.TextBoxEA.Text);
                                insertUser.Parameters.AddWithValue("@FullName", this.TextBoxFN.Text);
                                insertUser.Parameters.AddWithValue("@Country", this.DropDownListCountry.SelectedItem.ToString());

                                insertUser.ExecuteNonQuery();
                                Response.Redirect("~/Login.aspx");
                            }
                            catch (Exception ex)
                            {
                                Response.Write(ex.Message);
                            }
                        }
                    }
                    else
                    {
                        Response.Write("User already Exists in Database");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
        }
    }
}
4

3 に答える 3

10

はい。いい練習。可能な限り最小の範囲で物を処分します。そうしないと、かなり後で行うためにGCに任せます。

于 2012-08-16T23:12:06.947 に答える
1

絶対にusingステートメントをネストできます。各usingステートメントは1つのオブジェクトにのみ適用されるため、複数のステートメントを破棄する必要がある場合は、複数のusingステートメントを使用してください。

さらに、2番目のコマンドを開く前に最初のコマンドを閉じることで、ネストを減らすことができます。

int temp;
using (SqlCommand selectUser = new SqlCommand(cmdStr, cn))
{
    temp = Convert.ToInt32(selectUser.ExecuteScalar().ToString());
}
if (temp == 0)
{
    string insCmd = ...;
    using (SqlCommand insertUser = new SqlCommand(insCmd, cn))
    {
        ...
    }
}
于 2012-08-17T00:47:43.920 に答える
1

usingネストされた使い捨てオブジェクトを扱う場合は、ステートメントの使用が必須であることに完全に同意します。

ただし、コードをさらに変更することをお勧めします。コードを読みやすく、テスト可能で、保守しやすいものにするために、関数合成を使用することをお勧めします。コードの本体を変更する方法は次のとおりです。

using (var cn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegConnectionString"].ConnectionString))
{
    cn.Open();
    if (checkUserExists(cn, this.TextBoxUN.Text))
    {
        Response.Write("User already Exists in Database");
    }
    else
    {
        addUser(cn, this.TextBoxUN.Text, this.TextBoxPass.Text, this.TextBoxEA.Text, this.TextBoxFN.Text, this.DropDownListCountry.SelectedItem.ToString());
        Response.Redirect("~/Login.aspx");
    }
    cn.Close();
}

このコードはよりコンパクトで、何が起こっているのかを推論するのが簡単です。

このコードの前に、次のようにcheckUserExistsとlamdbasを​​定義する必要があります。addUser

Func<SqlConnection, string, bool> checkUserExists = (cn, un) =>
{
    var query = "SELECT COUNT(*) FROM REGISTRATION WHERE UserName = @UserName";
    using (var command = new SqlCommand(query, cn))
    {
        command.Parameters.AddWithValue("@UserName", un);
        return Convert.ToInt32(command.ExecuteScalar().ToString()) != 0;
    }
};

Action<SqlConnection, string, string, string, string, string> addUser = (cn, un, pw, e, fn, c) =>
{
    string query = "Insert INTO REGISTRATION (UserName, Password, EmailAddress, FullName, Country) VALUES (@UserName, @Password, @EmailAddress, @FullName, @Country)";
    using (var command = new SqlCommand(query, cn))
    {
        command.Parameters.AddWithValue("@UserName", un);
        command.Parameters.AddWithValue("@Password", pw);
        command.Parameters.AddWithValue("@EmailAddress", e);
        command.Parameters.AddWithValue("@FullName", fn);
        command.Parameters.AddWithValue("@Country", c);

        command.ExecuteNonQuery();
    }
};

これらのそれぞれも非常に単純であり、それらの意図は明確であり、推論するのは簡単です。

それらはラムダであるため、不要なメソッドでクラスを詰まらせることはありません。すべて1つのメソッドに含まれています。素敵で、きちんと整頓されています。

もちろん、それらはすべてusingステートメントを使用します。

お役に立てれば。

于 2012-08-17T01:27:25.893 に答える