使用语句用法

时间:2013-12-04 11:25:35

标签: c# idisposable

如果MyClass实现IDisposable接口,那么两个给定的代码段是否会正确处理MyClass对象?哪种方法优于另一种方法?

代码1

public MyModel MethodOne()
{
    using (MyClass myClass = new MyClass())
    {
        var myModel = new MyModel();
        myModel.MyModelData = myClass.GetData();

        return myModel;
    }
}

代码2

public MyModel MethodTwo()
{
    var myData = new MyData();

    using (MyClass myClass = new MyClass())
    {
        myData = myClass.GetData();
    }

    var myModel = new MyModel();
    myModel.MyModelData = myData;

    return myModel;
}

4 个答案:

答案 0 :(得分:3)

它是相同的:对象将以两种方式处理。

编译器将using语句翻译为try块,在finally块中调用Dispose

finally保证在try块完成执行后执行,无论其执行路径如何。

无论如何,都保证会调用Dispose。

参考MSDN

作为一种风格和最佳实践恕我直言,最好在不再需要时立即处理对象,因为您将更早地释放资源,因为如果Dispose抛出异常,您将使用您的方法返回任何内容。并且它将更容易调试。

<强>更新

作为KrisVandermotten pointed out,有些情况下finally块不会执行。

  • Environment.FailFast
  • Uncatchable execeptions
  • 电源故障

答案 1 :(得分:3)

usingtry块翻译为finally。你的代码

using (MyClass myClass= new MyClass())
{
    myData = myClass.GetData();
}

相同
MyClass myClass= new MyClass();
try
{
    myData = myClass.GetData();
}
finally
{
    if (myClass != null)
        ((IDisposable)myClass).Dispose();
}

至于哪种方法更可取,两种解决方案都能正常工作。第二种是较早地处理物体,因此在许多情况下是优选的。没有必要保留对象,特别是如果他们使用外部资源。

但也有例外。您可能希望或需要更长时间地保持对象以实现您的目标,例如使用事务范围时。此外,如果处理原始对象,有时从一次性对象派生的对象(如您的情况)可能会变得无效。

答案 2 :(得分:2)

在这两种情况下,您可以依赖这样一个事实:如果构造了MyClass的对象并且方法完成,则该对象也会被处理掉。

在后一种情况下,对象的构造时间晚于第一种情况,并且它比第一种情况要早,但在两种情况下它都会被丢弃。

哪个更好?假设一个一次性物体以某种方式保留了需要被释放的东西,并且这种保留是昂贵的,在其他条件相同的情况下,更好的方法将是第二个。

那么为什么上面两个警告?

“如果构建了MyClass的对象”

在第二种情况下,对new MyData()的调用可能抛出异常,甚至没有尝试MyClass对象构造。在第一种情况下,构造此对象是第一件事。它可能会失败,但它会被尝试。当然,它也可能在第二种情况下失败。如果它失败了,没有什么可以处理的。

“并且方法完成”

如果在执行处置之前失去权力,将不会处理任何事情,并且还有一些其他病态情况无法保证执行finally块。

答案 3 :(得分:1)

恕我直言,第一个版本更简洁,因此更好,因为处置前的额外时间可能是微不足道的。构建一些对象并设置属性通常不需要很长时间。

只有在调用“myModel.DoSomethingThaTakesALongTime()”时才会考虑使用第二个版本。