我有以下代码:
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
如何解决问题?
答案 0 :(得分:7)
您正在尝试向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
实际上是 a HeaderA
- 所以这项工作相当于此
HeaderA header = new HeaderA();
header.Item = new List {new ItemB()};
当其他任何事情都希望header.Item
成为IEnumerable<ItemA>();
时,那就不好了 - 所以这个应该没问题:
ItemA itemA = header.Item.First();
...如果你在那里添加ItemB
,显然不会。
基本上,您正在寻找通用协方差 - 但您只能在接口和委托上声明(而不是在诸如Header<TItem>
之类的类上),并且仅在类型参数不是由于Item
setter而在输入位置使用。
也许更重要的是,你的设计看起来非常复杂 - 我强烈怀疑如果你退后一步,你可以设计你的方法,试图做到这一点。