开发者

Failed cast: IList<T> to Custom Class implementing ICollection<T>

This is my custom collection declaration.

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

I am trying to cast to it from another collection IList<T>.

IList<HTMLMenu> htmlMenuList = new List<HTMLMenu>();
...
HTMLMenuCollection temp开发者_如何学JAVAColl = (HTMLMenuCollection)htmlMenuList;

I have no idea why this won't work. If I cast IList<T> to ICollection<T> it works just fine, but with this I get an invalid cast exception. What am I doing wrong?


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


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


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.


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.


Another work-around could be to use the AddRange(IEnumerable<HtmlMenu>) method that is provided to HtmlMenuCollection through the implementation of ICollection<HtmlMenu>.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜