Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declare IDisposable for the class or interface?

Starting from the following situation:

public interface ISample
{
}

public class SampleA : ISample
{
   // has some (unmanaged) resources that needs to be disposed
}

public class SampleB : ISample
{
   // has no resources that needs to be disposed
}

The class SampleA should implement the interface IDisposable for releasing resources. You could solve this in two ways:

1. Add the required interface to the class SampleA:

public class SampleA : ISample, IDisposable
{
   // has some (unmanaged) resources that needs to be disposed
}

2. Add it to the interface ISample and force derived classes to implement it:

public interface ISample : IDisposable
{
}

If you put it into the interface, you force any implementation to implement IDisposable even if they have nothing to dispose. On the other hand, it is very clear to see that the concrete implementation of an interface requires a dispose/using block and you don't need to cast as IDisposable for cleaning up. There might be some more pros/cons in both ways... why would you suggest to use one way preferred to the other?

like image 987
Beachwalker Avatar asked May 09 '12 10:05

Beachwalker


People also ask

What is an IDisposable interface?

IDisposable is an interface that contains a single method, Dispose(), for releasing unmanaged resources, like files, streams, database connections and so on.

How can we use IDisposable class?

For implementing the IDisposable design pattern, the class which deals with unmanaged objects directly or indirectly should implement the IDisposable interface. And implement the method Dispose declared inside of the IDisposable interface. We do not directly deal with unmanaged objects.

Why IDisposable interface is used?

IDisposable is defined in the System namespace. It provides a mechanism for releasing unmanaged resources. When your application or class library encapsulates unmanaged resources such as files, fonts, streams, database connections, etc, they should implement the IDisposable interface or the IAsyncDisposable interface.

When should you use IDisposable?

You should implement IDisposable when your class holds resources that you want to release when you are finished using them. Show activity on this post. When your class contains unmanaged objects, resources, opened files or database objects, you need to implement IDisposable .


5 Answers

Following the Inteface Segregation Principle of SOLID if you add the IDisposable to the interface you are giving methods to clients that are not interested in so you should add it to A.

Apart from that, an interface is never disposable because disposability is something related with the concrete implementation of the interface, never with the interface itself.

Any interface can be potentially implemented with or without elements that need to be disposed.

like image 118
Ignacio Soler Garcia Avatar answered Oct 13 '22 08:10

Ignacio Soler Garcia


If you apply the using(){} pattern to all your interfaces it's best to have ISample derive from IDisposable because the rule of thumb when designing interfaces is to favor "ease-of-use" over "ease-of-implementation".

like image 21
Felice Pollano Avatar answered Oct 13 '22 08:10

Felice Pollano


Personally, if all ISample's should be disposable I'd put it on the interface, if only some are I'd only put it on the classes where it should be.

Sounds like you have the latter case.

like image 30
Jamiec Avatar answered Oct 13 '22 08:10

Jamiec


An interface IFoo should probably implement IDisposable if it is likely that at least some some implementations will implement IDisposable, and on at least some occasions the last surviving reference to an instance will be stored in a variable or field of type IFoo. It should almost certainly implement IDisposable if any implementations might implement IDisposable and instances will be created via factory interface (as is the case with instances of IEnumerator<T>, which in many cases are created via factory interface IEnumerable<T>).

Comparing IEnumerable<T> and IEnumerator<T> is instructive. Some types which implement IEnumerable<T> also implement IDisposable, but code which creates instances of such types will know what they are, know that they need disposal, and use them as their particular types. Such instances may be passed to other routines as type IEnumerable<T>, and those other routines would have no clue that the objects are eventually going to need disposing, but those other routines would in most cases not be the last ones to hold references to the objects. By contrast, instances of IEnumerator<T> are often created, used, and ultimately abandoned, by code which knows nothing about the underlying types of those instances beyond the fact that they're returned by IEnumerable<T>. Some implementations of IEnumerable<T>.GetEnumerator() return implementations of IEnumerator<T> will leak resources if their IDisposable.Dispose method is not called before they are abandoned, and most code which accepts parameters of type IEnumerable<T> will have no way of knowing if such types may be passed to it. Although it would be possible for IEnumerable<T> to include a property EnumeratorTypeNeedsDisposal to indicate whether the returned IEnumerator<T> would have to be disposed, or simply require that routines which call GetEnumerator() check the type of the returned object to see if it implements IDisposable, it's quicker and easier to unconditionally call a Dispose method that might not do anything, than to determine whether Dispose is necessary and call it only if so.

like image 6
supercat Avatar answered Oct 13 '22 07:10

supercat


IDispoable being a very common interface, there's no harm having your interface inheriting from it. You will so avoid type checking in your code at the only cost to have a no-op implementation in some of your ISample implementations. So your 2nd choice might be better from this point of view.

like image 4
Seb Avatar answered Oct 13 '22 09:10

Seb