失败转换:IList <t>到实现ICollection <t> </t> </t>的自定义类

时间:2010-09-09 17:15:57

标签: c# exception collections casting

这是我的自定义集合声明。

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

我正试图从另一个集合IList<T>投射到它。

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

我不知道为什么这不起作用。如果我将IList<T>转换为ICollection<T>它可以正常工作,但是这样我会得到一个无效的强制转换异常。我做错了什么?

5 个答案:

答案 0 :(得分:5)

它没有强制转换,因为List<HTMLMenu>根本没有实现HTMLMenuCollection,即使它具有相同的成员集。

答案 1 :(得分:5)

将继承视为“是一种”关系。

然后您可以将其视为因为HTMLMenuCollectionList<HTMLMenu>但不是每个List<HTMLMenu>都是HTMLMenuCollection(因为List<HTMLMenu>不会继承来自HTMLMenuCollection)。

您可以从List转换为IList到ICollection的原因如下:

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

public interface IList<T> : ICollection<T> // and more

答案 2 :(得分:0)

HTMLMenuCollection未实施IListICollection广告投放有效,因为它们都继承自ICollection

此外,您正在从ListHTMLMenuCollection进行向上转换,但由于HTMLMenuCollection未从List继承而无法转换,因此无效因为编译器会认为HTMLMenuCollection有更多数据(即使它没有)而不是List,所以工作正常。

将列表传递给构造函数可能更有用,并且ICollection方法的内部实现只是传递给您在内部存储它的任何容器字段。

答案 3 :(得分:0)

.net中的转换是在运行时完成的,因此您必须查看实例的类型而不是声明的变量类型。 htmlMenuList实例的类型为List<HTMLMenu>,由于HTMLMenuCollection不是List<HtmlMenu>,因此无法投放到HtmlMenuCollection

答案 4 :(得分:0)

另一种解决方法是使用AddRange(IEnumerable<HtmlMenu>)通过实施HtmlMenuCollection提供给ICollection<HtmlMenu>的方法。