C# C中IDisposable的模板方法模式#

C# C中IDisposable的模板方法模式#,c#,.net,design-patterns,dry,idisposable,C#,.net,Design Patterns,Dry,Idisposable,我发现在C#中实现一次性模式的关键是要有一个抽象基类,它从IDisposable接口实现Dispose()方法,并提供一个受保护的虚拟一次性(bool)方法。然后子类需要覆盖一次性(bool),并始终执行以下操作: if(!disposed&&disposing) { //在此处配置资源 这是真的; } 我的问题是:不可能重用这个模式吗?我不希望必须在每个子类中管理这个“已处置状态”。我们可以有这样的抽象基类: 公共抽象类AbstractResource:IDisposable { priva

我发现在C#中实现一次性模式的关键是要有一个抽象基类,它从IDisposable接口实现Dispose()方法,并提供一个受保护的虚拟一次性(bool)方法。然后子类需要覆盖一次性(bool),并始终执行以下操作:

if(!disposed&&disposing)
{
//在此处配置资源
这是真的;
}
我的问题是:不可能重用这个模式吗?我不希望必须在每个子类中管理这个“已处置状态”。我们可以有这样的抽象基类:

公共抽象类AbstractResource:IDisposable
{
private bool myDisposed=false;
受保护的抽象void ReleaseUnmanagedResources();
受保护的虚拟void ReleaseManagedResources()
{
//(可选)重写此项以显式调用其他IDisposable对象的Dispose()
}
公共空间处置()
{
处置(真实);
总干事(本);
}
私有无效处置(bool处置)
{
如果(!myDisposed)
{
如果(处置)
{
ReleaseManagedResources();
}
ReleaseUnmanagedResources();
myDisposed=true;
}
}
~AbstractResource()
{
处置(虚假);
}
}
那么这个类的用户只需要实现ReleaseUnmanagedResources和(可选)ReleaseManagedResources。没有必要和布尔人打交道


我发现这也提出了类似的方法。但就是这样!没有人提到它。这种方法有缺陷吗?

这种方法最大的缺陷是它占用了有限的资源。。。从一个类派生的能力意味着,如果我使用您的实现,我基本上可以告别OOP,因为我需要从您的类派生许多类,而不能像实现接口那样从另一个类派生它们

因此,在现实世界中,有些类使用基类,有些为业务目的滚动它们自己的基类,它们已经合并了
IDisposable
,有些只是实现接口。我不能代表所有人说话,但我宁愿使用工具(例如R#)将相同的构造应用于所有类,而不是将各种东西混合在一起


如果我们有能力从多个基类派生,这可能是一件事,但在C#中我们没有。这比你想象的更糟糕。如果您有这样的类继承权,您可能需要在每个方法和属性中检查
disposed
,因为类对象可能会在非托管资源的生命周期之后很久才存在,以确保您永远不会访问disposed资源。这意味着您的抽象类实际上没有多大帮助

没有你想象的那么糟糕。您可能不应该首先实现终结器(
~AbstractResource()
)或完整的Dispose模式

人们普遍认为班级需要这些,而实际上根本不应该有它们。仅因为您在类中使用非托管资源,但如果您使用的资源是按其自身类型处置的,则不一定意味着类需要
IDisposable
。如果由
IDisposable
控制的资源已经由另一种类型完成,那么实现
IDisposable
并不意味着需要终结器

这篇文章也值得您花费时间:


是的,这是完全正确的。但这里的重点是;您真正需要使用finalizer实现完整的
IDisposable
模式的时候几乎永远不会发生。只有当您的原始资源让您的手脏了,并且其中大多数已经在框架中的某个地方实现了一个
IDisposable
包装器时,您才需要这样做。您的抽象类是否处理非托管资源?关于“确保您永远不会访问已处置的资源”,这是实现IDisposable的任何类都需要考虑的问题,不是吗?不仅仅是我的抽象基类。顺便说一句,谢谢你的文章!