C#编译器是否自动处理IDisposable对象?

时间:2013-01-07 09:26:29

标签: c# .net idisposable compiler-optimization

假设我有一个方法public static Rectangle DrawRectangle(Vector origin, Vector size),它返回Rectangle : IDisposable

类型的对象

如果我只调用方法DrawRectangle(origin, size),但没有将返回值赋给变量myRectangle = DrawRectangle(origin, size),编译器会自动检测到并调用DrawRectangle(origin, size).Dispose(),或者我必须自己动手吧?

5 个答案:

答案 0 :(得分:3)

没有。点。

最终他终结了,但没有。它不会自动调用Dispose。

答案 1 :(得分:3)

如果您的Rectangle类实现IDisposable,请尽可能尝试using( ) { ... }语句。

Msdn link

答案 2 :(得分:2)

编译器将代码构建到程序集中,并且不对任何执行负责。 .net运行时运行代码,更具体地说,垃圾收集器处理内存清理。通常最好的做法是在using块中调用实现IDisposable的对象。例如:

使用(var obj = new object) {     ......做你的东西 }

这将有助于运行时了解对象何时超出范围并提前清理它,但只要您不继续引用对象,运行时最终将清理它并为您处理它。

答案 3 :(得分:1)

如果您希望CLR调用Dispose方法,通常建议您在类中实现所谓的Dispose pattern。但是,我不会依赖CLR并且不会等待GC收集对象并改为使用using子句。

答案 4 :(得分:1)

我只能想到两种情况,编译器会自动调用dispose;最明显的是:

using(var obj = ... )
{
  // some code
}

这是一个明确的说明,说“最后,无论成功或失败,如果obj非空,请致电obj.Dispose()”。基本上它扩展到:

{
   var obj = ...
   try {
       // some code
   } finally {
       if(obj != null) obj.Dispose();   
   }
}

另一个是foreach,其中迭代器被放置 - 虽然它有点复杂,因为IEnumerator没有指定IDisposable是必需的(相比之下,{ {1}} 确实指定了),IEnumerator<T>甚至不需要技术IEnumerable,但基本上是:

foreach

可以表示为(虽然规范可能会略有不同):

foreach(var item in sequence) {
   // some code
}

在所有其他情况下,处置资源是您的责任。

如果您不确保调用{ var iter = sequence.GetEnumerator(); using(iter as IDisposable) { while(iter.MoveNext()) { // note that before C# 5, "item" is declared *outside* the while var item = iter.Current; // some code } } } ,那么在GC最终收集对象之前不会发生任何事情; 如果 有终结器(没有,通常不是),将调用终结器 - 但这与{{1}不同}。它 可能 (取决于每个类型的实现)最终与Dispose()做同样的事情:但它可能不会。