2010-09-09 71 views
3

这是我的自定义收集声明。失败演员:IList <T>到自定义类执行ICollection <T>

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

将继承看作是'是'的关系。

然后,你可以把它看成是因为HTMLMenuCollectionList<HTMLMenu>但并不是每个List<HTMLMenu>HTMLMenuCollection(因为List<HTMLMenu>不从HTMLMenuCollection继承)。

,你可以从列表到的IList到ICollection的投其原因如下:

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

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

它没有投射,因为List<HTMLMenu>根本没有执行HTMLMenuCollection,即使它具有相同的一组成员。

+0

好吧,我正在密集我猜。 IList 实现ICollection 它不应该使用该共同的参考来进行演员? – joshlrogers 2010-09-09 17:19:26

+0

@joshlrogers - 有一个共同的参考是不够的。它们的实施方式不同。 IList可以实现HTMLMenuCollection不实现的几个功能(从而使它们不兼容)。 – 2010-09-09 17:22:51

0

HTMLMenuCollection没有实现IListICollection演员工作,因为他们都从ICollection继承。

此外,你从List上溯造型到HTMLMenuCollection,这将无法工作,因为HTMLMenuCollection不是从List继承,也不管升频不能工作,因为编译器会考虑HTMLMenuCollection有更多的数据(甚至如果不是)比List

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

0

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

0

另一种解决方法可能是使用AddRange(IEnumerable<HtmlMenu>)方法,该方法通过执行ICollection<HtmlMenu>而提供给HtmlMenuCollection