ca9*_*3d9 0 c# generics covariance contravariance
我有以下代码:
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)
}
Run Code Online (Sandbox Code Playgroud)
最后的编译错误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
Run Code Online (Sandbox Code Playgroud)
如何解决这个问题?
你正试图添加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>();
Run Code Online (Sandbox Code Playgroud)
现在还记得那header是真正一个HeaderA-所以这个工作就相当于这个HeaderA头=新HeaderA(); header.Item = new List {new ItemB()};
当其他任何东西都期望header.Item成为时,那就不好了IEnumerable<ItemA>();- 所以这应该没问题:
ItemA itemA = header.Item.First();
Run Code Online (Sandbox Code Playgroud)
......如果你ItemB在那里加了一个,显然不会.
基本上,你正在寻找通用的协方差 - 但是你只能在接口和委托上声明(而不是在类等Header<TItem>),并且只有当type参数没有在输入位置使用时才会因为Itemsetter 而在这里.
也许更重要的是,你的设计看起来非常复杂-我强烈怀疑,如果你退一步,你可以设计自己的方式周围试图做到这一点摆在首位.