为啥是 IDisposable 接口? [复制]
Posted
技术标签:
【中文标题】为啥是 IDisposable 接口? [复制]【英文标题】:Why IDisposable interface? [duplicate]为什么是 IDisposable 接口? [复制] 【发布时间】:2020-11-09 14:00:01 【问题描述】:我看过很多文章说 IDisposable 的目的是关闭非托管对象,如数据库连接和第三方报告。但我的问题是,如果我可以在我的方法中处理非托管对象,我为什么要定义 Dispose 方法没有定义 Dispose() 方法?
举个例子,
class Report : IDisposable
public void GenerateReport()
Report rpt=new Report() //unmanaged object created
rpt.Dispose(); // Disposing the unmanaged object
private void Dispose()
//not sure why this block is needed
我的理解正确吗?
【问题讨论】:
嗨,杰。您可能会在***.com/questions/538060/… 找到您的问题(以及许多其他问题!)的答案。此外,如果这个问题最终被标记为重复,请不要感到惊讶 - 它之前已经介绍过:-) 【参考方案1】:垃圾收集器 (GC) 可在整个 .Net 框架中使用,运行良好,很容易被遗忘。但是,值得学习与他一起工作并利用他的可能性。为此,IDisposable 接口的正确实现是必要的,如果我们考虑适当释放托管和非托管资源,则其基本形式有时是不够的。
这是扩展版本,在这种情况下非常有用。 在某种程度上回答了你的问题:
public class DisposableExtended: IDisposable
private bool isDisposed = false;
public void Dispose ()
this.Dispose (true);
GC.SupressFinalize (this);
protected void Dispose (bool disposing)
if (! this.isDisposed)
if (disposing)
// here we release managed resources (standard classes)
// here we release unmanaged resources (e.g. streams, etc..)
this .isDisposed = true;
~ DisposableExtended ()
this.Dispose (false);
【讨论】:
【参考方案2】:实现 IDisposable 接口的类可以在 using 块中使用。此解决方案的一大优点是,在离开块后,将自动调用在该区域中创建的对象的 Dispose 方法。这样,我们只能使用实现 IDisposable 接口的类。
//example :
using(var dClean= new DisposableClean())
//after leaving this using dClean will be automatically destroyed
您创建的对象需要公开一些方法,而不是必须命名为 Dispose()。你也可以称它为 Clean()。 Dispose() 是常规名称。
【讨论】:
【参考方案3】:是的,您可以定义自己的方式来释放资源,但许多现有代码都使用这种方式。如果您将代码分享给他人,请记住告诉他们以您的方式处理。
实现IDisposable
的一个“好处”是您可以通过使用诸如using
之类的语言结构间接调用Dispose
。
例如:
using(Stream s = File.OpenRead("HelloWorld.bin"))
//Do stuffs
【讨论】:
【参考方案4】:您是正确的,您的示例中不需要实现 IDisposable。示例是,如果您在编写的课程的生命周期内保留一个长寿命的对象。所以说你有这个:
public class Report : IDisposable
private Stream _reportStream; // This variable lives a long time.
public void WriteToStream(byte[] data)
_reportStream.Write(data, 0, data.Length);
public void Dispose()
_reportStream?.Dispose();
这是一个相当简单的示例,但它表明_reportStream
在类的长度内存在,并且需要与类同时进行清理和垃圾收集。没有什么能阻止你创建一个名为 CleanupObject()
的公共方法来做同样的事情,但是人们不能使用 using
块让运行时自动调用 Dispose():
using (var myReport = new Report())
// do a bunch of things with myReport;
// Here the runtime will call myReport.Dispose() for you.
// myReport isn't accessible from here, as it was declared in the using block
【讨论】:
以上是关于为啥是 IDisposable 接口? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Enumerable.Range 实现 IDisposable?
c# 中最简单的 IDisposable 模式是啥? [复制]
为啥 FxCop 坚持使用 IDisposable 作为结构