我的项目中有一段代码,其中包含了另一个使用块的使用块,我想知道这是一个好习惯还是只是矫枉过正(请注意我明白这是一个非常简单的代码片段,它仅用于说明目的):
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);
}
}
}
答案 0 :(得分:10)
是。好的做法。尽可能在最小的范围内处理东西,否则你要把它留给GC做一段时间。
答案 1 :(得分:1)
绝对可以嵌套using
语句。每个using
语句仅适用于一个对象,因此如果需要处理多个对象,请使用多个using
语句。
此外,您可以通过在打开第二个命令之前关闭第一个命令来减少嵌套。
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))
{
...
}
}
答案 2 :(得分: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
和addUser
lamdbas,如下所示:
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();
}
};
其中每一项都非常简单,其意图清晰易懂。
因为它们是lambdas,所以它们不会用不必要的方法堵塞你的类 - 它们都包含在一个方法中。不错,干净利落整齐。
当然,他们都使用using
语句。
希望这有帮助。