3

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??

keyboardP
  • 68,824
  • 13
  • 156
  • 205
Shezi
  • 1,352
  • 4
  • 27
  • 51

4 Answers4

10

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.

Community
  • 1
  • 1
H H
  • 263,252
  • 30
  • 330
  • 514
  • what do you mean by "that allows substitution". can you give me an example pelase? – Shezi Jun 13 '13 at 11:59
  • 2
    I've added an example but SO questions are not the right place to get basic tutorials. See these [google results](https://www.google.nl/search?q=c%23+tutorial+interface&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a). – H H Jun 13 '13 at 12:05
3

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.

Grant Thomas
  • 44,454
  • 10
  • 85
  • 129
  • can you eleborate a bit further please? I know what are interfaces, but what exactly is the difference? – Shezi Jun 13 '13 at 11:39
  • but an immediate user would also know the existence of class Dispose method by looking at the class definition. So what difference does it make? – Shezi Jun 13 '13 at 11:41
  • @AtharAnis I think the idea is that any responsible third-party developer using your class will recognize that it is `IDisposable` and ensure to call its `Dispose` method when they're done with it. EDIT: It's not so much that it has a `Dispose` method so much as it _is_ `IDisposable`. If it doesn't inherit the interface, then the `Dispose` method could mean anything. Bottom line, .NET developers in general understand and adhere to principles working with `IDisposable` classes. – Chris Sinclair Jun 13 '13 at 11:41
  • 1
    @AtharAnis Code can at least be 'genericised', such that you can check if a thing is disposable or not, whereas otherwise you would have to explicitly know, or use reflection to look up the relevant method. Also, without a contract specification, your 'custom' Dispose method could do anything! – Grant Thomas Jun 13 '13 at 11:43
  • @GrantThomas ok I got it so far, but say i implement IDisposable and inside its Dispose Method I don't dispose the unmanaged resources and instead generate new unmanaged resources. How would we justify that? – Shezi Jun 13 '13 at 11:48
  • 1
    @AtharAnis You can't justify that, it's a misuse and irresponsible. With any contract comes a matter of trust. – Grant Thomas Jun 13 '13 at 11:49
  • @GrantThomas what do you mean by a contract? is it an agreement kind of a thing? and if it is, then how would I know what contract does IEnumerable has? and what i should be doing with methods exposed by IEnumerable interface? – Shezi Jun 13 '13 at 11:53
  • You _can_ have an `IEnumerable` make changes (side effects) when iterating and cause all sorts of horrors with Linq. It doesn't mean you _should_. You _can_ have an `IDisposable` create unmanaged resources in its `Dispose` method, but it doesn't mean you _should_. You _can_ make implicit conversions throw exceptions, but it doesn't mean you _should_. I can only imagine if you did you might get a good talking to by your boss. .NET developers work against certain... "good behaviour" or culture in general because it makes sense and saves our sanity (usually). – Chris Sinclair Jun 13 '13 at 12:02
1

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.

Alex
  • 23,004
  • 4
  • 39
  • 73
0

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.

Peter Wishart
  • 11,600
  • 1
  • 26
  • 45
  • thats what my point is! so why would i use IDisposable ? Offcourse, Microsoft must have developed it for some reason. – Shezi Jun 13 '13 at 11:58
  • If your class is only used in one place, you're the only one that uses it, and these won't change, you can skip IDisposable. – Peter Wishart Jun 13 '13 at 12:41