When shouldn't I implement IDisposable? - c#

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?

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.

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.

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.

Related

Is it safe to create and use a disposable object inline?

I have seen so many times developers using a disposable object inline, here for instance. By inline I mean:
var result = new DataTable().Compute("1 + 4 * 7", null);
I know that the Dispose method won't be called, but since no reference is held to the object, how will the garbage collector handle it? Is it safe to use a disposable object like that?
I used a DataTable in my example because it is the only concrete example I found, but my question applies to disposable objects in general. I do not personally use them like that, I just wanted to know if they are handled diffently by the GC if they are used that way.
The key problem here is the timing when Dispose is called, which is just unknown in your example (providing a good implementation of IDisposable — see below). I'd consider using an IDisposable instance without a using statement a code smell. The class is implementing IDisposable for a reason, and thus you as a user should obey its contract.
However, note that in a correct implementation of IDisposable the class'es finalizer handles the disposal of an un-disposed object. Hence even if not instantiated within a using, the disposal shall be performed, but in unknown time and on a different (the GC's) thread.
I just wanted to know if they are handled diffently by the GC if they are used that way.
No, the GC treats all object alike and doesn't treat IDisposable implementations anyhow differently. However, in a correct implemenetation of IDisposable the Finalize method (invoked by the GC on every object unless suppressed on a per-object basis) call would lead to invoking the Dispose.
If the object that is being initialized inline has a destructor implemented, that destructor could be calling Dispose() after the object has gone out of scope.
However, the cleaner and correct way is to use a using statement because this could potentially lead to just instances of objects hanging around with no purpose.
It is not safe to use disposable objects in this way. Yes, no reference wont be held but the purpose of Disposable pattern is to dispose all unmanaged resources(like OS handles) which cannot be garbage collected.

how to dispose off objects that implement IDiposable and also the types of properties/methods invoked on them implement IDisposable

Little confused (and not sure) with the kind of C# objects that I'm dealing with the at the moment.
For example:
interface IMyInterface
{
IDictionary<string, ICustomPath> MyPathDictionary { get; }
}
which is implemented by a class the also implements IDisposable
class MyClass:IMyInterface,IDisposable
{
}
IMyInterface myInterface = new MyClass();
I know how to dispose off instance "myInterface" of object MyClass (either by a using statement or explicitly cast instance to IDisposable like
((IDisposable)myInterface).Dispose();
or
((MyClass)myInterface).Dispose(); in the finally block after I'm done with what I'm doing.
But I have something like the following line of code
IExampleInterface exampleInterface = some condition ? myInterface.MyPathDictionary[key]:myInterface.CreateSomething(key);
And MyPathDictionary[key] is a dictionary value (where the key is of type string) and value of type IExampleInterface which is implemented by another class called ExampleClass, which also implements IDisposable like.
class ExampleClass:IExampleInterface,IDisposable
{
}
Now my confusion is caused by the above conditional statement since analysis of my code with a proprietary tool says that myInterface.MyPathDictionary[key] is causing a leak of resources/memory. What I'm not sure of is that when I'm disposing off myInterface explicitly in the finally block of my C# code then shall I explicitly dispose off myInteface.MyPathDiciotnary[key] as well because if I already disposed off myInterface then an invocation of MyPathDictionary[key] on it (myInterface) should automatically be disposed off.
Any suggestions regarding this conundrum will be appreciated.
If MyClass owns these resources then ((IDisposable)myInterface).Dispose(); should dispose of them. It is a common pattern to have a disposable root object recursively call dispose on anything that it owns. That kills the entire object tree which is convenient and intuitive for callers.
The key question is whether the objects contained in MyPathDictionary are owned or not.
Your static analysis tool probably thinks that myInterface.MyPathDictionary[key] is a factory method that creates what it returns. Property get operations are method calls. To the tool this might look like a factory. This is a false positive.
On the other hand if you actually called myInterface.CreateSomething(key) then this probably did create something that must be disposed of. You need to ensure this. Either by always disposing v no matter where its value came from. Or, by differentiating between the two cases.
I'd just wrap v in using and be done with it. Makes it easy to review the code and conclude that it is correct.
If implementations of your interface need to be disposable, the best way to handle it is to change your interface so that it also implements IDisposable. That way its clear to all users of the interface that it needs to be disposed properly. If some implementations don't actually need to dispose anything that's fine, they just have an empty implementation.

Should we implement IDisposable if one member is IDisposable?

I think so. But take a look at a built-in class in ASP.NET:
public sealed class HttpPostedFile
{
public Stream InputStream { get; } // Stream implements IDisposable
// other properties and methods
}
Suppose I have an instance of HttpPostedFile called file. Since there is no Dispose method to explicitly invoke, file.InputStream.Dispose() won't be invoked until it's destructed, which I think goes against the original intention of IDisposable. I think the correct implementation should contain a standard IDisposable implementation. So, if one of the members implements IDisposable, the class needs to implement it too.
What are your opinions? It seems to be a bit complicated.
In general, you should implement IDisposable if you own the resource represented by the property - see this question for a discussion on this subject.
I'd say that because HttpPostedFile is instantiated during processing of an HTTP request, it doesn't own the stream, and hence doesn't dispose it. The stream will be disposed when the HTTP request processing finishes.
If your class creates one or more IDisposable objects and holds the only references to them, then your class should almost certainly implement IDisposable and dispose the IDisposable objects it created. If one or more IDisposable objects will be passed into the constructor of your class, then you need to consider a few scenarios:
Your creator may want to keep using the IDisposable after you're done with it, and will certainly know when it's no longer needed (the semantics of your class would let him know you're done with it).
Your creator won't want to use the IDisposable after you're done with it, and may not know when you're going to be done with it.
Your class may be used in some circumstances corresponding to (1) above, and in some circumstances (2), but your creator will know in advance which circumstance applies.
Your creator can't predict whether he's going to want to keep using the object after you're done with it.
For scenario #1, there's no need for you to implement IDisposable, though it might not be a bad idea to implement a do-nothing IDisposable handler and have your consumers use it, in case another scenario applies in future.
For scenario #2, your object should take ownership of the IDisposable, and should Dispose it when done. I don't really like having objects take unconditional ownership of IDisposables; I prefer to implement things as in #3.
There are two ways of handling #3. The one I prefer is for your object to take a parameter (either a Boolean or an enum) along with the IDisposable, indicating whether it is supposed to take ownership of the IDisposable. Your class unconditionally implements IDisposable; the implementation disposes of any objects it has taken ownership of, but not those it hasn't. An alternative is to have two subclasses with a common base class - one subclass implements IDisposable and the other does not. I prefer the former pattern, because it allows for the addition of a method to replace an IDisposable with a new one (of which it may or may not take ownership). For example, if I were implementing a control with an Image property, I would have a SetImage method which with a parameter to specify whether the control should own the passed-in image; that method would Dispose the old image if it owned it, and could then either take ownership of the new image or not.
bool OwnMyImage;
Image MyImage;
void SetImage(Image NewImage, bool TakeOwnership)
{
IDisposable oldDisposable; // Could reuse one variable for multiple IDisposables
if (OwnMyImage)
{
oldDisposable = Threading.Interlocked.Exchange(MyImage, null);
if (oldDisposable != null)
{
oldDisposable.Dispose();
}
}
OwmMyImage = TakeOwnership;
MyImage = NewImage;
}
Scenario #4 is complicated; the best way to handle it is probably for your object to implement IDisposable by raising a Disposed event. Your creator can use that event to do either Dispose the object if you were the last one using it, or adjust a flag or counter so that other code will know the object shouldn't be left undisposed on your behalf.
It depends.
Stream is also implemented by TextStream (possibly on top of StringBuilder), so no unmanaged resources are required.
HttpPostedFile may not use any unmanaged resources at all, so it's safe to postpone deconstruction until the garbage collector sees fit.

C# Using Statement and iDisposable

I have just discovered that best practise instructs that where any type implement iDisposable, then you should wrap that in a using statement to ensure the object is disposed of correctly, even in the event of an exception.
My question is, how can you easily tell which objects implement iDisposable? Or should I just wrap everything that I am unsure about in the using statement and then rely on the compiler to tell me at compile time?
Thanks.
You could ...
Look for the presence of a Dispose member
Look at the definition of your type (F12)
Do as you suggest, wrap in a using and see what the compiler says
Although, the best thing is to learn what IDisposable is used for, soon you will understand the types that do and should implement this interface. i.e. external resources, unmanaged type wrappers (GDI graphics objects for example), limited resources (database connections)
IDisposable is implemented for example by objects that give access to unmanaged or expensive resources, like files, database connections and things like that. So to a certain extent, you can guess. For the rest, intellisense tells you if the Dispose() method is available on the object.
how can you easily tell which objects implement iDisposable?
Programatically one can use.
IDisposable disposable = obj as IDisposable;
if(disposable!=null)
{
//this object implements IDisposable
}
else
{
//Not implement IDisposable interface
}
If it's a standard class, then the MSDN documentation page should say if it implements IDisposable or not. Third-party libraries also usually come with documentation. Otherwise, if you're using an IDE like Visual Studio, you can inspect the class (F12 key) and see what interfaces it implements.
If you right click and choose Goto Declaration you should get the object browser there you can se all interfaces implemented by the class.
Otherwise use the intellisense to check if the class has a Dispose() -method, in which case you use Using.
And lastly, if you try to use Using on something thats Not an IDisposable you´ll get a compiler error.
Using the Object Explorer you should be able to traverse the hierarchy to see the root of the object you're trying to use.
The compiler will warn you, though, if the variable that you're trying to use is not IDisposable:
using (int i = 1)
{
// ...
}
will give you an error:
Error 1 'int': type used in a using statement must be implicitly convertible to 'System.IDisposable'
You can check this way also
if (anyobject is IDisposable)
{
//it implemants IDisposable
}
If one can employ a "Using" statement and have it work, one generally should. One type of situation to watch out for is creating an object and passing it as a property of some other object. There are four approaches the framework can take here:
A snapshot is taken of the passed-in IDisposable. The receiving object will take care of disposing the snapshot; the supplier of the IDisposable is responsible for Disposing it, and it may do so at any time after the snapshot is taken.
A snapshot is taken of the passed-in IDisposable, without care of whether it's been disposed or not. The supplier is responsible for Disposing the IDisposable, but could legitimately do so at any time--even before it's passed in. The "Font" properties of controls seem to behave this way. If a Font object is going to be used only to set controls' Font properties, one could Dispose the font as soon as it's created and not have to worry about cleaning it up later.
The receiving object requires that the passed-in object not be Disposed until the receiving object is done with it, whereupon the receiving object will Dispose it.
The receiving object requires that the passed-in object not be Disposed until the receiving object is done with it, but the sending object is still responsible for Disposing it.
Unfortunately, Microsoft seems to use different approaches to IDisposable objects in different parts of the framework. Sometimes the best thing to do is dispose of the object immediately after setting the property, and see if that causes problems when the receiving object tries to use it.

Do I need to dispose transient disposable objects?

I have a class that creates several IDisposable objects, all of these objects are then passed to another 'manager' class in a 3rd party library. As I need some of the objects in later calls I kept a local field reference to the created objects so that I could access them at a later time. When I ran FxCop on the class it said that I should implement IDisposable, due to the disposable objects that I kept a reference to. My questions are:
Should I implement IDisposable for my class? (or is it the manager's responsibility?)
If so, should I only dispose the objects I kept a reference to? or should I find a way to dispose all objects I created.
My code:
public class MyClass
{
ClassThatIsDisposable aReference;
}
public MyClass(ManagerClass manager)
{
ClassThatIsDisposable transient=new ClassThatIsDisposable();
manager.Add(transient);
aReference=new ClassThatIsDisposable();
manager.Add(aReference);
}
public void LaterCall()
{
areference.Method();
}
The class that owns the object is the one that should dispose of them... It sounds like your manager is the owner, so he should dispose of the object.
If you're trying to avoid the FXCop warning then one option is to have MyClass request the disposable object from the manager each time is needs to use it. This way you won't have a member variable holding a reference to it. You could do this my having the Add() method return akey for the object that has been added and then use this key to retrieve the object from the manager when you need to use it.
If you create any disposable objects, you should either dispose them yourself or make sure you're handing them off to another class which will take responsibility for that.
In this case, I'd say it really depends on what the manager class is going to do. If that guarantees that it will dispose of anything that is added to it, you're okay. It does look like a somewhat odd design pattern though - I can't say I've used anything similar myself. That's not to say it's necessarily wrong/bad, but it would at least be worth taking another look to see if there's any way of avoiding this slight confusion of ownership.
Bear in mind that if the manager disposes the object you're holding a reference to, it's likely to be unusable afterwards.

Categories

Resources