106

我只想知道returnusing块内调用是否安全/好方法。

例如。

using(var scope = new TransactionScope())
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}

我们知道最后一个花括号 dispose()将被取消。但是在上述情况下会发生什么,因为return将控制权跳出给定范围(AFAIK)......

  1. 我的scope.Complete()被​​叫了吗?
  2. 作用域的dispose()方法也是如此。
4

6 回答 6

159

return在你的块内调用是完全安全的using,因为 using 块只是一个try/finally块。

在上面的示例中,在 return 之后true,范围将被释放并返回值。return false,并且scope.Complete()不会调用。Dispose然而无论如何都会被调用,因为它位于 finally 块中。

您的代码与此基本相同(如果这样更容易理解):

var scope = new TransactionScope())
try
{
  // my core logic
  return true; // if condition met else
  return false;
  scope.Complete();
}
finally
{
  if( scope != null) 
    ((IDisposable)scope).Dispose();
}

请注意,您的交易将永远不会提交,因为无法scope.Complete()提交交易。

于 2012-08-02T12:02:31.590 回答
7

这很好 -finally子句(这是子句的右花括号在using幕后所做的)总是在离开范围时执行,无论如何。

但是,这仅适用于 finally 块中的语句(使用 时无法显式设置using)。因此,在您的示例中,scope.Complete()永远不会被调用(我希望编译器会警告您有关无法访问的代码)。

于 2012-08-02T12:02:48.883 回答
2

一般来说,这是一个很好的方法。但在你的情况下,如果你在调用之前返回scope.Complete(),它只会破坏 TransactionScope。取决于你的设计。

因此,在这个示例中,Complete() 没有被调用,并且作用域被释放,假设它继承了 IDisposable 接口。

于 2012-08-02T12:03:17.643 回答
2

scope.Complete 绝对应该在之前调用return。编译器将显示警告,并且永远不会调用此代码。

关于return它本身 - 是的,将其称为内部using语句是安全的。using被翻译成try-finally块在幕后,finally块肯定会被执行。

于 2012-08-02T12:07:48.857 回答
1

In the example you have provided, there is a problem; scope.Complete() is never called. Secondly, it is not a good practice to use return statement inside using statements. Refer to the following:

using(var scope = new TransactionScope())
{
    //have some logic here
    return scope;      
}

In this simple example, the point is that; the value of scope will be null when using statement is finished.

So it is better not to return inside using statements.

于 2012-08-02T12:09:49.307 回答
0

在这个例子中,scope.Complete() 永远不会执行。但是,return 命令将清除堆栈上分配的所有内容。GC 将处理所有未引用的内容。所以,除非有不能被 GC 拾取的对象,否则没有问题。

于 2012-08-02T12:07:35.603 回答