问题
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