Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将一个Using块包装在另一个Using块中-是否过度使用?_C#_Using Statement - Fatal编程技术网

C# 将一个Using块包装在另一个Using块中-是否过度使用?

C# 将一个Using块包装在另一个Using块中-是否过度使用?,c#,using-statement,C#,Using Statement,我在我的项目中有一段代码,其中我将一个Using块包装在另一个Using块中,我想知道这是一个好的实践还是一个过激的做法(请注意,我知道这是一个非常简单的代码片段,它仅用于说明目的): 对。良好做法。在尽可能小的范围内处理这些内容,否则您将把它留给GC在一段时间后执行。绝对可以使用语句嵌套。每个using语句仅适用于一个对象,因此,如果需要处理多个对象,请使用多个using语句 此外,可以通过在打开第二个命令之前关闭第一个命令来减少嵌套 int temp; using (SqlCommand s

我在我的项目中有一段代码,其中我将一个Using块包装在另一个Using块中,我想知道这是一个好的实践还是一个过激的做法(请注意,我知道这是一个非常简单的代码片段,它仅用于说明目的):


对。良好做法。在尽可能小的范围内处理这些内容,否则您将把它留给GC在一段时间后执行。

绝对可以使用语句嵌套
。每个
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))
    {
        ...
    }
}

我完全同意在处理嵌套的一次性对象时必须使用
语句

然而,我建议进一步修改代码。为了使代码可读、可测试和可维护,最好使用函数组合。下面是我将如何更改代码主体:

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();
    }
};
Func checkUserExists=(cn,un)=>
{
var query=“从注册中选择计数(*),其中UserName=@UserName”;
使用(var命令=新的SqlCommand(查询,cn))
{
command.Parameters.AddWithValue(“@UserName”,un);
返回Convert.ToInt32(command.ExecuteScalar().ToString())!=0;
}
};
动作addUser=(cn、un、pw、e、fn、c)=>
{
string query=“在注册中插入(用户名、密码、电子邮件地址、全名、国家/地区)值(@UserName、@Password、@EmailAddress、@FullName、@Country)”;
使用(var命令=新的SqlCommand(查询,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();
}
};
其中每一项都非常简单明了,它们的意图也很清楚,也很容易推理

因为它们是lambda,所以它们不会用不必要的方法阻塞类——它们都包含在一个方法中。漂亮、整洁、整洁

当然,它们都使用
语句


希望这有帮助。

太好了,我不认为会有什么伤害。GC从不处理对象。它只是释放内存。您必须直接或自己使用终结器显式地处理对象。对于实现
IDisposable
的所有内容,请使用
using
,并尽可能快地处理它。与问题稍微相关,但是,通过将内部代码块提取为单独的私有方法,可以减少嵌套using块的混乱。这样一来,逻辑就不会嵌套得太深以至于很难阅读,但您仍然有正确的外部“使用”块来处理资源。@DanBryant谢谢,我实际上有一个库类,我可以在其中处理所有这些“低级别”但是为了让我的帖子更容易阅读和理解,我选择了这条路线。只是一个简短的评论——捕捉异常是个坏主意。你应该从你的代码中删除它们,除非你只是为了调试而把它们放进去,并且你打算以后再删除它们。
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();
    }
};