views:

185

answers:

5

I understand that any Collection (here I am talking about regular non-generic) should have implemented ICollection, IEnumerable and IList incase of regular object collection or IDictionary in case of Dictionaries.

[Still, the question I ask is not specific to collections]

IList is derived from ICollection and IEnumerable

ICollection is derived from IEnumerable

Is it not just enough to make a collection (E.g. ArrayList) implement IList?

In the Object browser it is displaying that collection classes (E.g. ArrayList) are implementing IList, ICollection, and IEnumerator.

I understand that even if we specify all three Collections, .Net is going to accept the definitions only once.

But my question is,

  1. Is there any best practice or recommendation that guides us to specify all three interfaces for the collection class (Or any class similar to this)?

  2. Or is it just the propery of Object Browser that displays it as 3 separate implementations? [Just checked and found that its not the property of Object browser. Object browser just displays the interfaces that are specified in the class definition]

+1  A: 

In order to access an object via an interface, the class definition for the object must explicitly define that it implements the interface...

For example, I can have the following:

interface IAnimal {
  public void Yelp();
}

and the following class:

class Dog {
  public void Yelp() { 
     // do yelping
  }
}

Now, the dog does indeed yelp; however, because it doesn't declare that it implements IAnimal, I can't do the following:

IAnimal poodle = new Dog();
poodle.Yelp();

In order to fix this the definition for Dog must be changed to:

class Dog : IAnimal {
  public void Yelp() { 
     // do yelping
  }
}
Chris Lively
The definition for the class OR A BASE CLASS must specify that it implements the interface. If Dog implements IAnimal, and Poodle inherits from Dog, then a Poodle can be cast to an IAnimal and the Yelp function invoked upon it.
supercat
+2  A: 

Is it not just enough to make a collection (E.g. ArrayList) implement IList?

It is enough. Declaring a class:

public MyCollectionClass : IList {
}

That will mean your MyCollectionClass implements IList, ICollection, and IEnumerable.

In the Object browser it is displaying that collection classes (E.g. ArrayList) are implementing IList, ICollection, and IEnumerator.

This is either a detail of the Object Browser, or else the base class has simply implemented the collection classes by specifying all interfaces. There really isn't any driving reason to do so, however.

qstarin
+4  A: 

I believe it's just the object browser that displays it that way. I've just tried this:

using System.Collections;
using System.Collections.Generic;

public class Foo : IEnumerable<int>, IEnumerable
{
    public IEnumerator<int> GetEnumerator() { return null; }
    IEnumerator IEnumerable.GetEnumerator() { return null; }

}

public class Bar : IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator() { return null; }
    IEnumerator IEnumerable.GetEnumerator() { return null; }
}

Loading this into the object browser showed both interfaces on both classes.

Note that sometimes there can be a point to redeclaring an interface if you're inheriting from another implementation - it allows you to reimplement the interface if it's previously been implemented explicitly or in a non-virtual way. I don't believe that's the case here, but it's worth mentioning.

In general though, you definitely don't have to specify all the interfaces, and I wouldn't generally do so.

Jon Skeet
This doesn't work for me in VS2010. In addition, for my custom classes, the object browser is omitting implied interfaces.
ladenedge
@ladenedge: This was in VS2010 for me, too (VS2010 Pro if that's relevant). It's showing me the interfaces in "Base types". What's it showing you there?
Jon Skeet
Hi, Thank you for your response. But its not the property of Object Browser. I found that sometime back. If we derive it only from IList, object browser shows only IList. If we derive from both IList and IEnumerable, object browser shows both.
SaravananArumugam
@Saravandandss: Again, that's not my experience (using the VS2010 object browser). I've implemented just `IList` in a third class, and it's still showing all the interfaces in the Object Browser. Maybe it depends on the compiler version?
Jon Skeet
@Jon Skeet: they're all there in the tree view, but they are still displayed in distinct ways - [quick pic of what I mean here](http://www.cryptofreak.org/~jnmiller/img/implied-interfaces.png) (VS2010 Pro for me, too, fwiw). Additionally, the bottom right MSDN-like class definition view does not include the implied interfaces to any extent.
ladenedge
@ladenedge: Interesting - my view in VS2010 Pro doesn't have that at all, it just shows it as being flat. Maybe it's because I've got the PowerTools installed?
Jon Skeet
@Jon Skeet: nope - the [power tools](http://go.microsoft.com/fwlink/?LinkId=194327) didn't seem to impact my object browser at all. I'm using VS v10.0.30319.1, fwiw.
ladenedge
@ladenedge: Hmm... I don't have the .1 on the end. I wonder if that's it?
Jon Skeet
@Jon Skeet: I suppose it's possible, though I have a feeling each of us is just confused about what exactly the other is looking at, heh.
ladenedge
+2  A: 

Now, I think you are asking, given

interface IA {};
interface IB : IA {};
interface IC : IB {};

What's the difference between:

class MyClass : IC {};

and

class MyClass : IA, IB, IC {};

And the answer is, absolutely nothing. The second version makes it design a bit clearer to other programmers, but either will generate identical code.

James Curran
+1  A: 

I believe this is just either to be clear to developers, or to help enforce the interface structure. What I mean is, imagine you have an interface for data structure classes, and you implement IDataObject. IDataObject then implements ISecurable, and ILoggable. Regular classes you create could just implement IDataObject, but what if the creator of IDataObject changes the implementation later and drops ILoggable? This may change the functionality of your code. So, to prevent this, when you create your class that inherits from IDataObject, you can explicitly say that you want to also implement ISecurable and ILoggable, just to be safe.

I don’t know for sure why they did that with IList, but those two reasons are my best guess on why.

Robert Seder