多个using块在C#中的使用方法是什么?

4

我正在开发一个需要访问数据库的应用程序。使用“using”语句是很好的选择,因为它能确保对象得到正确处理并且不需要显式代码来实现这一点。

所以我有些困惑,在哪里使用“using”,在哪里则不需要。

public int route(Route r)
{
    try
    {
        using (SqlConnection con = new SqlConnection(connectionString))
        {
            using(SqlCommand com = new SqlCommand("",con))
            {
                using (SqlDataReader sdr = com.ExecuteReader())
                {
                }
            }
        }
    }
    catch (Exception e)
    {
    }
}
3个回答

15

任何时候,当您创建的对象实现了IDisposable时,在使用或不使用using语法糖的情况下,释放它都是明智的选择

using块语法糖(而不是手动调用.Dispose())的好处是,即使出现异常并且流离开了using块,Dispose()仍然会被调用

此外,请注意,您可以堆叠多个using,无需嵌套缩进:

using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand com = new SqlCommand("",con))
using (SqlDataReader sdr = com.ExecuteReader()) // Still need to open connection ...
{
   ...

顺便提一下,using 的另一个好处是,如果在 using 中声明了 IDisposable 变量,那么该变量就是只读的,不能在块内重新赋值,例如:

using (SqlDataReader sdr = com.ExecuteReader())
{
   sdr = new SqlDataReader() // Error

如果我不使用嵌套缩进,那么我如何确保对象被正确释放,因为对象是在块的末尾被释放的。 - Hot Cool Stud
2
@HotCoolStud 不用担心,编译器会处理这个问题。它足够智能,可以理解你想要嵌套语句,因此这是有效的语法。 - Selman Genç
我从来不知道可以这样做!:D 但我真的希望你是对的,编译器会按照LIFO的顺序处理对象,否则这可能会成为一个问题。 - Crono

4
你可以这样简化它:
using (SqlConnection con = new SqlConnection(connectionString))
using(SqlCommand com = new SqlCommand("",con))
using (SqlDataReader sdr = com.ExecuteReader())
{
     ...
}

使用语句被翻译为 try/finally 块。因此,即使出现异常抛出,你的对象也将被 Disposed。因此,如果你有一个可处理的对象,并且想确保在使用后它将被处置,你可以使用 using 语句。记住,这是一种语法糖,类似于这样:

SqlCommand cmd;
try
{
    cmd = new SqlCommand();
    ...
}
finally
{
   ((IDisposable)cmd).Dispose();
}

3

using块而言,这看起来还不错。

但是,除非您打算实际处理异常,否则请不要在此处使用try/catch块。否则,您只是隐藏了可能的错误,这是不正确的。


Pokemon异常处理...“ gotta catch em all ”。这是一种非常糟糕且非常常见的代码味道。 - Stephen Turner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接