如何处理班级比封装可支配实例?
-
14-10-2019 - |
题
interface IMyInterace
{
void Open();
object Read();
void Close();
}
class MyImplementation : IMyInterface
{
public void Open() { /* instantiates disposible class */ }
//...
public void Close() { /* calls .Dispose(); */ }
}
是否有一个很好的方法来处理这种情况,以确保班上的可支配实例被调用? (对呼叫者没有信号,他们必须在文档中调用“关闭”。)Imyinterface的实现不一定封装Idisposible实例,并且在整个应用程序的一生中都被关闭并重复重新开放。
我正在考虑这样做:
- 实现在Myimplentation中实现IDISPOSIBLE。
- 将DISPOSE()设置为close()。
- 将呼叫添加到CLOSS()或DISPOSE()到开放的开始,以确保关闭以前的呼叫。
Imyinterface的用户不知道他们正在使用什么实现,因此我不确定使MyImplementation Doposible具有多少价值,并且并非所有实现都会封装Idisposibles。
解决方案
除了在这里的答案外:
如果此类仅通过接口使用(通常/有时),我会建议从idisposable继承Imyinterace。
这将使您的用户以一致的方式使用这些对象。当然,您可能需要添加(虚拟)将方法添加到实际上不需要的类的类中。但是,好处在于一致性和灵活性:如果一个班级在将来发生变化,以便它确实需要dispose()?
一种最小的方法:
interface IMyInterace : IDisposable { }
sealed class MyImplementation : IMyInterface
{
public void Open() { /* instantiates disposible class */ }
public void Close() { /* calls _myField.Dispose(); */ }
public void Dispose() { Close(); } // only use this short form in a sealed class
}
其他提示
处理此问题的标准方法就是简单 MyImplementation
实施 IDisposable
.
正如约翰提到的那样,您的第一个项目符号是正确的。
有时 Close()
方法在功能上是同义词 Dispose()
, ,并且存在以保持语义一致性与抽象。也就是说,补充 Open()
方法。其他时间, Close()
将允许您重新开放,但是 Dispose()
不应该。因此,您的第二个子弹点也很好。
子弹点3不一定适用,因为不应重复使用处置对象。如果您需要打电话 Open()
同样,您需要使用新实例。实际上, Open()
方法应该抛出 ObjectDisposedException
一次 Dispose()
已被调用(通过检查私人 disposed
布尔国旗)。如果您希望该对象在关闭后支持重新开放,则可以考虑使用 Debug.Assert()
和/或抛出例外 Open()
被称为没有 Close()
. 。这将有助于防止对这些情况的草率管理。
确保遵循完整的一次性模式,这不仅仅是实现界面:
bool disposed;
public void Dispose() // don't make virtual!
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// dispose of managed resources here, for example:
// if(resource != null) { resource.Dispose(); }
}
}
// dispose of unmanaged resources here
disposed = true;
}