views:

112

answers:

4
public interface IMenuCollection<T> : ICollection<T>
public class HTMLMenuCollection: IMenuCollection<HTMLMenu>

This is my custom collection definition. I am trying to cast to it from another collection IList.

IList<HTMLMenu> htmlMenuList = new List<HTMLMenu>();
...
HTMLMenuCollection tempColl = (HTMLMenuCollection)htmlMenuList;

I have no idea why this won't work. If I cast IList to ICollection it works just fine, but with this I get an invalid cast exception.

Any help would be greatly appreciated.

+4  A: 

It doesn't cast because List<HTMLMenu> simply does not implement HTMLMenuCollection, even if it has the same set of members.

dtb
Ok, I am being dense I guess. IList<T> implements ICollection<T> shouldn't it use that common reference to make the cast?
joshlrogers
@joshlrogers - Having a common reference isn't enough. They are implemented differently. IList could implement several features that HTMLMenuCollection does not implement (thus making them incompatible).
Joel Etherton
+5  A: 

Think of inheritance as a 'is a' relationship.

Then you can think of it as being because HTMLMenuCollection is a List<HTMLMenu> but not every List<HTMLMenu> is a HTMLMenuCollection (since List<HTMLMenu> doesn't inherit from HTMLMenuCollection).

The reason that you can cast from a List to IList to ICollection is the following:

public class List<T> : IList<T>, ICollection<T> // and more

and

public interface IList<T> : ICollection<T> // and more
Justin Niessner
A: 

HTMLMenuCollection does not implement IList. The ICollection cast works because they both inherit from ICollection.

Also, you're upcasting from a List to an HTMLMenuCollection, which won't work because HTMLMenuCollection is not inheriting from List, and regardless the upconvert can't work since the compiler will consider HTMLMenuCollection to have more data (even if it doesn't) than a List.

It might be more useful to pass the list into a constructor, and have the internal implementations of the ICollection methods just pass to whatever container field you're storing it in internally.

johaanfaust
A: 

Casting in .net is done at run-time, so you must look at the type of the instance instead of the declared type of the variable. The type of htmlMenuList instance is List<HTMLMenu>, which cannot be casted to HTMLMenuCollection because List<HtmlMenu> is not, and does not inherited from HtmlMenuCollection.

tia