我的问题是为什么我需要IDisposable?我有一个消耗一些资源的课程 需要被释放。我有两个选择
没有IDisposable
class SomeUtilityClass
{
public Stop()
{
// free resources
}
}
使用IDisposable
class SomeUtilityClass, IDisposable
{
public void Dispose()
{
// free resources
}
}
那我为什么需要IDisposable呢?它没有如何命名该功能。
class Program
{
public Main(..)
{
SomeUtilityClass _class = new SomeUtilityClass();
// clean up when we've done
_class.Stop();
// OR
_class.Dispose();
}
}
答案 0 :(得分:5)
因为C#支持IDisposable,您可以使用酷using
语法:
using (IDisposable someDisposable = new ...)
{
// your code with someDisposable
}
这实际上是由编译器转换为:
IDisposable someDisposable = new ...
IDisposable someDisposable2 = someDisposable ;
try
{
// your code with someDisposable
}
finally
{
if (someDisposable2 != null)
{
someDisposable2.Dispose();
}
}
因此,如果在using
块内发生任何异常,则无论如何都会处理您的对象。
答案 1 :(得分:3)
当您的类消耗非托管资源时,您应该只使用IDisposable,并且需要立即释放它们(流,数据库等)。
当有未处理的异常导致你的线程被卸载时,它还为CLR提供了一种“清理”的方法。
调用IDisposable会将对象标记为可立即用于垃圾收集,但如果未正确实现,则可能导致对象被提升为垃圾收集生成,这会导致内存压力(如果需要,请参阅通过c#3的Jeffery Richters CLR完整的解释)。
一个快速的谷歌转向了这个: http://kleahy-technical.blogspot.com/2009/01/idisposable-and-garbage-collection.html我建议你阅读IDisposable模式,何时使用它,什么时候不要及其对GC和状态的影响。
编辑: stackoverflow上还有大量的信息: Use of Garbage Collection?
答案 2 :(得分:2)
在您的情况下,实施IDisposable没有太大意义,因为您可以手动处理您的资源。
IDisposable的一个常见用途是当您公开处理数据连接的接口时,您希望所有派生类在完成后进行处置。
考虑一下:
public interface IDataCtx
{
void CallDB();
}
public class MyDataCtx : IDataCtx
{
private SqlConnection dc;
public MyDataCtx() { dc = new SqlConnection(); dc.Open(); }
public void CallDB();
{
dc.Something();
}
}
允许你做这样的事情:
IDataCtx ctx = new MyDataCtx();
ctx.CallDB();
但是等等,那个开放的连接怎么样?哦,哦!
如果你创建了IDataCtx : IDisposable
(并在你的派生ctx中实现了代码),你可以这样做:
IDataCtx ctx;
using (ctx = new MyDataCtx())
{
ctx.CallDB();
}
保证您使用的IDataCtx的任何实现,它将始终被处置(即使在例外的情况下)。
无论如何,这就是我如何使用它。 (加上它只是一种很好的做法)。
答案 3 :(得分:1)
IDisposable
与using
关键字进行互动,以便您自行清理,例如:
using (var file = new FileStream(...))
{
file.Write(...);
}
在上面的代码中,FileStream
在使用块完成后立即关闭,而不是等待垃圾收集。
答案 4 :(得分:1)
这是C#语言中使用的约定。
您还可以获得漂亮的using
声明。
using (SomeUtilityClass _class = new SomeUtilityClass()) {
} // Dispose is automatically called
答案 5 :(得分:1)
除了能够使用using语句之外,它还为垃圾收集器提供了一个提示,可以从内存中删除该对象。
答案 6 :(得分:1)
如果您的类拥有非托管资源或您的类拥有托管的IDisposable资源,那么您应该实现IDisposable接口。
可以在此处找到关于何时实施IDisposable和Finalizer的简单易读的文章:http://nitoprograms.blogspot.com/2009/08/how-to-implement-idisposable-and.html