C# 如何处理IDisposable?
假设我有这三门课C# 如何处理IDisposable?,c#,.net,idisposable,C#,.net,Idisposable,假设我有这三门课 abstract class MyBase { //some base code here } class Foo : MyBase, IDisposable { //got at least a field I should dispose } class Bar : MyBase, IDisposable { //got at least a field I should dispose } 我有几节这样的课。我有一个拥有列表的类。我如何正确地
abstract class MyBase
{
//some base code here
}
class Foo : MyBase, IDisposable
{
//got at least a field I should dispose
}
class Bar : MyBase, IDisposable
{
//got at least a field I should dispose
}
我有几节这样的课。我有一个拥有列表的类。我如何正确地处理所有这些类,而不必测试/强制转换以获得正确的类型,然后进行处理?您可以使用:
foreach (var disposable in list.OfType<IDisposable>())
{
disposable.Dispose();
}
foreach(类型()列表中的变量)
{
一次性的,一次性的;
}
我想说,一般来说,拥有这种类层次结构是个坏主意;这意味着客户机不能以同样的方式使用“MyBase的任何实例”,因为对于特定类型还有额外的合同。使Base
实现IDisposable
会更简洁,即使一些特定类型实际上并不需要它。如果可处置性是基类合同的一部分,为什么不明确说明它
abstract class MyBase : IDisposable
{
//some base code here
//an abstract "implementation" of the interface
public abstract void Dispose();
}
通过这种方式,您可以确保其所有子代实际上都是一次性的。您还可以创建集合类而不是常规列表,如下所示:
class MyBaseCollection : IEnumerable<MyBase>
{
private List<MyBase> innerCollection;
....
public void DisposeItems()
{
// call Dispose on each item here
}
}
这样子代就别无选择,只能实现这些方法,否则代码将无法编译
如果大多数类不需要处理,但其中一些仍然需要处理,我将在基类中声明虚拟方法:
public virtual void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposing){}
这个默认实现对于大多数子体来说已经足够好了,那些确实需要处理的子体可以随意覆盖它
另外,由于Dispose()
方法的代码几乎总是相同的,因此可以实现其中一个,而将另一个作为虚拟的,甚至是抽象的
//should not be overridden
public virtual void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
//must be overriden
public abstract void Dispose(bool disposing);
今后,请更仔细地使用您的示例-遵循.NET命名约定(foo
和bar
=>foo
和bar
),使用正确的接口名称(iDisposable
=>iDisposable
),不要尝试使用关键字(base
)作为标识符。这些错误不会阻止我们帮助你,但它们会不必要地分散你的注意力。@JonSkeet编辑了这个名字。TY我应该在MyBase上实现IDisposable
,即使它没有任何东西要处理吗?@im_a_noob:如果所有(甚至大多数)派生类都需要IDisposable
,那么它是一个有效的选项。与System.IO.Stream
比较,请注意MemoryStream
没有要处理的内容。不,只需添加public abstract void Dispose()代码>因此满足编译器的要求。查找std模式。您需要一个受保护的虚拟void Dispose(bool disposing){}
。
//should not be overridden
public virtual void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
//must be overriden
public abstract void Dispose(bool disposing);