在返回一个实现IDisposable的对象后,我应该调用.Dispose()吗?
myDisposableObject Gimme() {
//Code
return disposableResult;
disposableResult.Dispose();
}
换句话说,我返回的对象是一个副本,还是对象本身?谢谢:)
是对象本身。不要在这里调用Dispose,即使你把顺序颠倒过来,使它被调用。
不,你不应该。你返回的是对象的引用,所以没有复制。在.NET中,除非你特别要求,否则对象永远不会被复制。
而且,即使有情况下你应该这样做,你也不能用这样的代码处理对象。后面的代码是 return
语句将永远不会被执行,你会得到一个关于不可达代码的警告。
到目前为止,所有的答案都没有提到一件事,那就是你的 应 处置该对象,如果 Gimme()
抛出一个异常。 例如
MyDisposableObject Gimme()
{
MyDisposableObject disposableResult = null;
try
{
disposableResult = ...
// ... Code to prepare disposableResult
return disposableResult;
}
catch(Exception)
{
if (disposableResult != null) disposableResult.Dispose();
throw;
}
}
disposableResult.Dispose();永远不会运行,它是不可到达的代码,因为它总是返回前面的行。 将方法调用用using staement包装起来,并以这种方式处置对象,例如
using (DisposeableObject myDisposableObject = gimme())
{
//code.
}
该 .Dispose()
反正将永远无法达到
编辑。 在我看来,不,你不应该这样做. 你这样做会毁掉对象。
如果一个你正在使用的对象实现了 IDisposable
,你应该构建和使用在一个 using
语句--这将确保它被正确处理。
using(var mydisposableObject = new Gimme())
{
// code
}
根据你的代码构造,你要返回的是一次性对象,所以在调用 Dispose
将永远不会到达。
如果你返回对象,你应该 不 在你回来之前处置它。必须由打电话的人自己来处置。
这一行。disposableResult.Dispose();
将不会被执行。返回的 "东西 "不是对象的副本。它是一个对象的引用,所以调用者将在创建的对象上进行操作。Gimme
而他(调用者)应该记得处理这个对象。
你可以把你的代码包在tryfinally块中。
try{
int a = 0;
return;
}
finally{
//Code here will be called after you return
}
我同意不要处置这个对象,它是通过引用传递的。在产卵对象时,有一种特殊的情况我可以想到,一个类包装另一个类,并分发对象。你不希望被分配的对象是同一个对象的引用 所以你要克隆或传递一个对象的副本,然后销毁原件,但是如果原件是该类型所有产卵的标准图像,该对象不是专门为每次调用而创建的,而且你预计在短时间内会有大量的产卵,你可能想保留它,因为你可以从该图像中产卵一个新的对象,而不需要再次实例化它... ... 我会选择将这个对象的所有属性锁定为只读,并将只读对象转为可在现实世界中使用的读写对象。当对象被传递为值复制或克隆时,它不应该在自身内部运行任何线程,然而如果它是线程,只要引用是1对1的关系,传递它的引用是完全没有问题的,如果你有多个指向一个对象的指针,他们同时对那个 "运行中的图像 "对象进行读写,你可能会开始发生碰撞,一个值没有被安全存储,下一个pinger请求并分配相同的值。当我在学校的时候,我们在很大程度上没有讨论过的一件事就是对象状态。面向对象的原理是根深蒂固的,但理解为什么要建立这些原理总是需要时间。我是背单词的,我学的是面向对象的风格,然后转入更多的程序化风格。
myDisposableObject disposableResult = new myDisposableObject();
在这里 disposableResult
是对新创建对象的引用。所以当你把这个引用返回给调用方法时,这个引用仍然指向堆中的创建对象。因此,你可以在调用方法中安全地处理它。
你不能在返回的方法中使用.Dispose(),调用者应该实现这个功能。