如果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;
}
答案 0 :(得分:3)
它是相同的:对象将以两种方式处理。
编译器将using
语句翻译为try块,在finally块中调用Dispose
。
finally
保证在try块完成执行后执行,无论其执行路径如何。
无论如何,都保证会调用Dispose。
参考MSDN
作为一种风格和最佳实践恕我直言,最好在不再需要时立即处理对象,因为您将更早地释放资源,因为如果Dispose抛出异常,您将使用您的方法返回任何内容。并且它将更容易调试。
<强>更新强>
作为KrisVandermotten pointed out,有些情况下finally块不会执行。
答案 1 :(得分:3)
using
被try
块翻译为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()”时才会考虑使用第二个版本。