我看到很多像这样的代码:
public class MyWcfService : IMySerciceContract, IDisposable
{
private DatabaseOperations _dataAccess;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
_dataAccess.Dispose();
}
}
MyWcfService类将在IIS或WAS中托管,其中没有人会在其上显式调用Dispose。我的想法是让这个类实现IDisposable是没有意义的,你最好在using语句中包含_dataAccess的使用。据我所知,实现IDisposable的类的期望是该类的用户将在using块声明中实例化它。以上示例是不好的做法,考虑到没有用户会显式调用Dispose?如果我们依赖GC来清理,如上例所示,GC甚至会调用Dispose,还是只调整终结器?
答案 0 :(得分:1)
...,没有人会明确地调用Dispose。我的想法是让这个类实现IDisposable是没有意义的......
关键是,在您的代码中缺少调用Dispose
的终结器。
...据我所知,实现IDisposable的类的期望是该类的用户将在using block声明中实例化它...
通常,实现IDisposable
的类的期望是有一些东西需要处理。 using
只是一个语法糖,它实现IDisposable
完全没有。
...如果我们依赖GC来清理,如上例所示,GC甚至可以调用Dispose,还是只调整终结器?
GC不会自动调用Dispose
,因此您需要让终结器调用它。
public partial class MyWcfService: IMySerciceContract, IDisposable {
private DatabaseOperations _dataAccess;
public void Dispose() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if(!this.disposed) {
if(disposing) {
_dataAccess.Dispose();
}
this.disposed=true;
}
}
// so it make sense now ..
~MyWcfService() {
this.Dispose(false);
}
bool disposed;
}
如果消费者未调用Dispose
,则终结器会在必要时调用它。了解如何实施[IDisposable interface]。
答案 1 :(得分:1)
“DatabaseOperations _dataAccess”是一个类成员,由您的类“拥有”。它是IDisposable,所以你的课也应该是。并且您应该始终实现完整的标准dipose模式以保持一致性。
如果_dataAccess是您在方法范围内使用和丢弃的类方法中的局部变量,那么使用块是合适的。
通常,您希望以这样的方式编写代码,以便为代码的用户提供最大程度的清理控制。这意味着如果你的任何成员都是IDisposable。但对于非成员IDisposable对象,那么'使用'是可行的方法。
当然,这同样适用于您班级的消费者。如果他们将您的类作为成员字段嵌入,他们应该使他们的类IDisposable。否则,他们可以使用'使用'与您的类对象..等等。