我有以下代码:
class Header<TItem> where TItem : IItem { IEnumerable<TItem> Item { get; set; } }
class HeaderA : Header<ItemA> { public HeaderA(int a) {...} }
class HeaderB : Header<ItemB> { public HeaderB(int b) {...} }
interface IItem {...}
class ItemA : IItem { }
class ItemB : IItem { }
public static List<Header<IItem>> list = new List<Header<IItem>>
{
new HeaderA(1)
}
最后一个new HeaderA(1)
上的编译错误是
Error 1 The best overloaded Add method
'System.Collections.Generic.List<NS.Header<NS.IItem>>.Add(NS.Header<NS.IItem>)'
for the collection initializer has some invalid arguments
如何解决问题?
您正试图将Header<ItemA>
添加到List<Header<IItem>>
。这需要从Header<ItemA>
到Header<IItem>
的转换,而这种转换并不存在。它不存在是有充分理由的。想象一下你的代码是有效的。。。那么这将起作用:
List<Header<IItem>> list = ...; // As per code
Header<IItem> header = list[0];
header.Item = new List<IItem>();
现在请记住,header
实际上是一个HeaderA
,所以这个工作等价于HeaderA header=新HeaderA();头球项目=新列表{new ItemB()};
当其他任何东西都期望header.Item
是IEnumerable<ItemA>();
时,这是不好的——所以这个应该没问题:
ItemA itemA = header.Item.First();
如果你在里面加了一个ItemB
,显然不会。
基本上,您正在寻找通用协方差,但您只能在接口和委托上声明(而不能在Header<TItem>
等类上声明),并且只有当类型参数由于Item
setter而没有在输入位置中使用时。
也许更重要的是,你的设计看起来非常复杂——我强烈地怀疑,如果你后退一步,你可以从一开始就设计你的方法。