Shezi
Shezi

Reputation: 1342

why use IDisposable when a dispose() method could be written in a class

Title explains the question quite clearly. I want to know why would I implement IDisposable interface that provides only one method definition in a class, where, in another class, I can explicitly define a dispose() method and release all unmanaged resources.

Say I have these two classes

class MyClass : IDisposable
{
    public void Dispose() { }
}

class MyClass2
{
    public void Dispose() { }
}

What exactly is the difference between MyClass and MyClass2??

Upvotes: 3

Views: 227

Answers (4)

Henk Holterman
Henk Holterman

Reputation: 273179

A very concrete consequence in this example, specific to IDisposable, is that the first class can be used in a using() {} statement and the second one cannot:

using (var c1 = new MyClass())  { ... }  // Ok
using (var c2 = new MyClass2()) { ... }  // Error

The more general answer is that interfaces provide a contract that allows substitution. Search for 'the benefits of interfaces' or something like that for more information. For instance this SO answer has a list.

An example of substitution:

public interface IRepository { ... }

public class RealRepository : IRepository { ... }
public class MockRepository : IRepository { ... }

class MyController { public IRepository { get; set; }

This (sketchy) fragment shows a Controller that can be used with a real (Db) Repository and tested with a Mock Repository.

Upvotes: 10

Alex
Alex

Reputation: 23300

IDisposable is just one interface, but the question might be generalized "Why should I implement an interface when I can simply implement methods?". Here is another example which might shed some light: it matters when it comes to consuming the classes.

interface IAnimal
{
    void PutInZoo(Zoo);
}

class Cat: IAnimal
{
    public void PutInZoo(Zoo theZoo);
}

class Fish
{
   public void PutInZoo(Zoo theZoo);
}

class Zoo
{
    public void PutInZoo(IAnimal animal)
    {
         animal.PutInZoo(this);
    }

    public Zoo()
    {
         this.PutInZoo(new Cat());  // Ok
         this.PutInZoo(new Fish()); // Nope, Fish doesn't implement IAnimal
    }
}

The most prominent side effect of implementing an interface, aside from compilation errors, is that if the interface changes you must abide to it.

In this example, if IAnimal changes its definition and PutInZoo is renamed to FreeFromZoo, Fish would still compile (and probably break its consumers) but Dog won't: it no longer implements IAnimal.

Upvotes: 1

Peter Wishart
Peter Wishart

Reputation: 12270

The difference between the two is just that Class1 officially implements the interface.

Class2 just potentially implements it, although these terms aren't great; the implementation/presence of the method may be the same for both.

Upvotes: 0

Grant Thomas
Grant Thomas

Reputation: 45083

Because IDisposable defines something of a universal contract of conventional semantics for freeing resources. It's a known pattern that can be relied upon to expose a relevant method that does a certain thing (Henk gives a specific example of this in the language with using). Nothing but the immediate user of your code knows of the existence of your class's Dispose method.

In your first instance, the class implements the contract, and can be used in a conventional way.

Upvotes: 3

Related Questions