Does the C# compiler automatically dispose of IDisposable objects?

删除回忆录丶 提交于 2019-12-13 17:13:17

问题


Assuming I have a method public static Rectangle DrawRectangle(Vector origin, Vector size) which returns an object of type Rectangle : IDisposable

If I call only the method DrawRectangle(origin, size), but do not assign the return value to a variable myRectangle = DrawRectangle(origin, size), will the compiler automatically detect this and call DrawRectangle(origin, size).Dispose(), or do I have to do it myself?


回答1:


There are only two scenarios I can think of where the compiler automatically calls dispose; the most obvious would be:

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

which is an explicit instruction to say "at the end, whether success or failure, if obj is non-null, call obj.Dispose()". Basically it expands to:

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

The other is foreach, where-by the iterator is disposed - although it gets a bit complicated, because IEnumerator doesn't specify that IDisposable is required (by contrast, IEnumerator<T> does specify that), and technically IEnumerable is not even required for foreach, but basically:

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

could be expressed as (although the spec may say it slightly differently):

{
    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
        }
    }
}

In all other cases, disposing resources is your responsibility.

If you don't ensure that Dispose() is called, then nothing will happen until GC eventually collects the object; if there is a finalizer (there doesn't have to be, and usually isn't), the finalizer will be invoked - but that is different to Dispose(). It may (depending on the per-type implementation) end up doing the same thing as Dispose(): but it may not.




回答2:


No. Point.

Eventually he finalizer does, but no. It does not automatically CALL Dispose.




回答3:


If your Rectangle class implemets IDisposable, try the using( ) { ... } statment when posible.

Msdn link




回答4:


The compiler builds code in to assemblies and is not responsible for any execution. The .net runtime is what runs your code and more specifically, the garbage collector deals with memory clean up. It is generally best practice to call objects that implement IDisposable inside of a using block. E.g:

using (var obj = new object) { ... do your stuff }

This will help the runtime understand when your object goes out of scope and clean it up earlier, but as long as you dont hold on to a reference to an object, the runtime will eventually clean it up and dispose it for you.




回答5:


If you want the CLR to call the Dispose method, it is usually recommended to implement the so called Dispose pattern in your class. However, I would not rely on CLR and wouldn't wait for GC to collect an object and use the using clause instead.



来源:https://stackoverflow.com/questions/14193066/does-the-c-sharp-compiler-automatically-dispose-of-idisposable-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!