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>
.
精彩评论