0

我有以下代码:

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

如何解决问题?

4

1 回答 1

7

您正在尝试将 a 添加Header<ItemA>List<Header<IItem>>. 这需要从Header<ItemA>to转换Header<IItem>- 并且该转换不存在。它不存在是有充分理由的。想象一下您的代码是有效的......那么这将起作用:

List<Header<IItem>> list = ...; // As per code
Header<IItem> header = list[0];
header.Item = new List<IItem>();

现在记住这header实际上一个HeaderA- 所以这个工作相当于这个 HeaderA header = new HeaderA(); header.Item = 新列表 { 新 ItemB() };

当其他任何东西都期望header.Item成为IEnumerable<ItemA>();- 所以应该没问题时,这并不好:

ItemA itemA = header.Item.First();

...如果您在其中添加了一个,显然不会ItemB

基本上,您正在寻找泛型协方差 - 但您只能在接口和委托上声明它(而不是在诸如 之类的类上Header<TItem>),并且只有当类型参数由于设置器而没有在输入位置使用时,因为它在这里Item.

也许更重要的是,你的设计看起来非常复杂——我强烈怀疑,如果你退后一步,你可以设计自己的方式来尝试首先做到这一点。

于 2012-09-13T23:30:18.083 回答