Alfie
Alfie

Reputation: 2350

When shouldn't I implement IDisposable?

Firstly, sorry if this is considered a duplicate - I know it is a common topic, but I have looked and not found a satisfactory answer.

There are a lot of questions asking when to use IDisposable, but from everything I've read, I just can't see why you wouldn't implement it in every class you make. What is there to lose? Does it have a big performance hit?

Part of my understanding of IDisposable is that one of the things it does is: Dispose()ing other IDisposables owned by the object. Forgive my ignorance, but does this apply only to fields/properties of the given object, or does it also extend to objects created within its methods too?

For instance, if a Font was created inside a method within a class that implements IDisposable, but that Font wasn't initialised with a using block, or .Dispose()d explicitly at the end of the method; would it be disposed when its IDisposable parent/class was GCd/disposed? Or otherwise, would the Font never be disposed?

I don't mean to digress, but if it is true that it would act as a 'catch all' like this (effectively disposing of any erroneous child IDisposable objects that would otherwise be left undisposed), isn't that reason alone enough to justify always implementing IDisposable whenever possible?

Upvotes: 3

Views: 2210

Answers (3)

supercat
supercat

Reputation: 81277

An object should implement IDisposable if it will know of things that need to happen sometime before the end of the universe, and nothing else is going have the knowledge and impetus necessary to ensure that those things get done; the Dispose method lets the object know that it had better do those things immediately, because otherwise they'll likely never get done.

An abstract type or interface should implement IDisposable if it is likely that instances of a derived or implementing that type might know of things that need to happen sometime before the end of the universe, and the last entity holding a reference is apt to know that it's an instance of something derived from or implementing the abstract or interface type, rather than as something which implements a more specific type that implements IDisposable.

A type which implements an interface that inherits IDisposable will be required to implement IDisposable, whether or not it would have any other reason for doing so.

Types which have reason to implement IDisposable should do so. Types which don't, shouldn't.

ADDENDUM

To understand why one shouldn't always implement IDisposable, it may be helpful to consider the real cost of doing so. The amount of time required for the processor to call a do-nothing Dispose method is trivial, but that isn't the real consideration. The bigger issue comes when one considers that most objects fit one of four descriptions:

  • Objects which encapsulate resources, and need to have one clearly-defined owner

  • Objects which encapsulate mutable state, and need to have one clearly-defined owner.

  • Objects of immutable types, which do not need to have clearly-defined owners.

  • Instances of mutable types which will never be exposed to code that could mutate them, and do not need to have clearly-defined owners.

Correct use of mutable objects generally requires keeping track of who owns them, as is the case with objects that hold resources. Likewise, if an object with mutable state is used to encapsulate mutable state for another object, proper use of the latter object will require keeping track of who owns it, as is the case with objects encapsulating other objects that own resources. The difference is between objects with resources and those with mutable state is that when an instance of a mutable type is used to encapsulate the state of an immutable object (ensuring the instance is never exposed to code that would mutate it), it will no longer be necessary to keep track of who owns it. By contrast, it's necessary to track ownership of objects which encapsulate other objects that hold resources, even if those objects are semantically immutable.

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 942267

The rule is very simple, you need to implement IDisposable if you have any fields in your class that are of a type that is disposable. So that you can dispose them.

What happens inside a method has little to do with the fields of your class. If you create the font and store it in a field then yes, the above rule says that you need a Dispose() method. If you don't but just use the font to draw something, like you normally do, then always use the using statement so you immediately dispose the font after you are done using it.

Upvotes: 9

OneFineDay
OneFineDay

Reputation: 9024

Most objects don't need it. The framework takes good care of Garbage Collection. COM objects and Graphics objects are among the ones that do and should implement IDisposable for good clean up. Yes there may be some inherent performance loss when recycling objects.

Upvotes: 1

Related Questions