在处理时,没有变量的using语句会做什么?

时间:2014-02-24 12:51:51

标签: c# transactions using-statement

我一直习惯使用变量和赋值。现在我喜欢这个类DbProviderConnection:

public class DbProviderConnection : IDisposable
{
    public DbConnection Connection { get; set; }
    public DbTransaction Transaction { get; set; }

    public DbTransaction BeginTransaction()
    {
        Transaction = Connection.BeginTransaction();
        return Transaction;
    } 

    //... and so on
}

现在我想要像这样使用它:

using (DbProviderConnection cnctn = _planDb.CreateOpenConnection())
{
    using (cnctn.BeginTransaction())
    {
        //...
        cnctn.Transaction.Commit();
    }
}

我的问题是:DbProviderConnection.Transaction.Dispose是否被调用?

4 个答案:

答案 0 :(得分:17)

C# Specification 8.13使用声明定义为

using-statement:
   using (resource-acquisition) embedded-statement

资源获取的位置

resource-acquisition:
    local-variable-declaration
    expression

在第一种情况下,您使用通过局部变量声明获取资源。在第二种情况下,通过表达式获取资源。因此,在第二种情况下,资源将是cnctn.BeginTransaction()调用的结果,即来自DbTransaction类的DbProviderConnection。使用语句在使用后处理其资源。所以,是的,DbProviderConnection.Transaction.Dispose()将被调用。

更新:根据同一篇文章,您的第二个使用块将被翻译为

DbTransaction resource = cnctn.BeginTransaction();
try
{
    //...
    cnctn.Transaction.Commit();
}
finally 
{
   if (resource != null) 
      ((IDisposable)resource).Dispose();
}

答案 1 :(得分:4)

来自规范:

  

8.13使用声明

表格的使用声明

using (ResourceType resource = expression) statement

当ResourceType是可空值类型或动态以外的引用类型时,扩展名为

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

表格的使用声明

using (expression) statement

具有相同的三种可能的扩展...资源变量在嵌入语句中是不可访问的,并且是不可访问的。

因此,cnctn.BeginTransaction()返回的对象将在块退出时被处理,但在相关块内无法访问。

答案 2 :(得分:3)

是的,将会调用Dispose。 using语句仅适用于一次性对象。像这样:

using (DbProviderConnection cnctn = _planDb.CreateOpenConnection())
{
    using (cnctn.BeginTransaction())
    {
        // ...
        cnctn.Transaction.Commit();
    } // Here BeginTransaction.Dispose() is called.
} // Here DbProviderConnection.Dispose() is called.

答案 3 :(得分:0)

BeginTransaction返回的对象将被处理。

BeginTransaction返回DbTransaction,这样就会被处理