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 子句中关闭连接。鉴于上面的代码,假设如果出现异常就会关闭连接是否合理?

4

5 回答 5

19

你是对的; 该using语句编译为try/finally

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

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

(强制转换IDisposable为以防万一显式ResourceType实现IDisposable

于 2010-04-25T21:31:13.287 回答
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'
}

以前您可以重新分配,但仍会释放原始对象,而不是新分配的对象,您还会收到以下编译警告:

可能不正确地分配给本地 'd',它是 using 或 lock 语句的参数。Dispose 调用或解锁将发生在本地的原始值上。

于 2010-04-25T21:27:42.427 回答
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();
    }
}
于 2010-04-25T21:28:33.823 回答
1

Using() 确保在参数中实例化的项目将被丢弃,而不管在相关代码块中发生的情况。这包括关闭数据库连接,假设SQLiteConnection正确处理其处置。

于 2010-04-25T21:30:51.940 回答
1

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

于 2010-04-25T21:27:41.347 回答