C#中的using语句是否执行try/finally操作?

17

假设我有以下代码:

private void UpdateDB(QuoteDataSet dataSet, Strint tableName)
{
    using(SQLiteConnection conn = new SQLiteConnection(_connectionString))
    {
        conn.Open();
        using (SQLiteTransaction transaction = conn.BeginTransaction())
        {
            using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM " + tableName, conn))
            {
                using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter())
                {
                    sqliteAdapter.Update(dataSet, tableName);
                }
            }
            transaction.Commit();
        }
    }
}

C#文档指出,使用using语句后,作用域内的对象将被处理并释放。有些地方建议我们不需要使用try/finally子句。

通常我会在连接操作周围加上try/finally,而且我总是在finally子句中关闭连接。根据上述代码,假设出现异常,可以合理地认为连接将被关闭吗?


类似于 https://dev59.com/_HVC5IYBdhLWcg3wfhGL - Mark Byers
6
不是对你的问题的答案。请阅读关于 SQL 注入攻击的内容。 - Raj Kaimal
5个回答

20

你是正确的;using语句编译成try/finally块。

编译器将using(resource) statement;转换成以下代码:

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      if (resource != null) ((IDisposable)resource).Dispose();
   }
}

如果ResourceType显式实现了IDisposable接口,那么将其强制转换为IDisposable


如何最好地释放一个无法在using语句中实例化、被重用或作为out参数传递的资源? - bjan
@bjan:这取决于具体情况。 - SLaks

10

是的,你需要使用try/finally或using语句。你不需要两者都用。

Using语句与try/finally几乎相同,只是在C# 3中你无法在using块内对变量重新赋值。

using (IDisposable d = foo())
{
     d = null; // Error:  Cannot assign to 'd' because it is a 'using variable'
}

以前你可以重新分配,但原始对象仍将被处置,而不是新分配的对象,并且您还会收到此编译警告:

可能是对使用或锁定语句的参数进行不正确的赋值。Dispose调用或解锁将在本地变量的原始值上发生。


如何最好地释放一个无法在using语句中实例化、被重用或作为out参数传递的资源? - bjan

6
是的,using语句基本上只是try ... finally块的缩写。
例如,以下代码...
using (MyDisposableType foo = new MyDisposableType())
{
    foo.DoSomething();
}

...将等同于以下内容...

{
    MyDisposableType foo = new MyDisposableType();
    try
    {
        foo.DoSomething();
    }
    finally
    {
        if (foo != null)
            ((IDisposable)foo).Dispose();
    }
}

1

如果出现异常,您可以假设连接将被关闭。


1

使用()可以确保在参数中实例化的项目将被处理,无论与关联代码块中发生了什么。这包括关闭数据库连接,假设SQLiteConnection正确处理其处置。


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