似乎没有要在这个问题上的任何问题,所以我会提出几个问题来回答。
什么是协变转换?
让我们假设我们有一些类型的Fruit
和Apple
和Banana
具有明显的关系; Apple
是一种Fruit
,依此类推。
协变转换是其中类型参数的可转换性意味着泛型类型的可转换性的转换。如果Apple
可转换为Fruit
,并Bowl<Apple>
可转换为Bowl<Fruit>
,然后Bowl<T>
在T.
什么是逆变转换协变?
甲逆变转换是一种协变转换该反转方向,而不是保存它。如果Eater<Fruit>
可转换为Eater<Apple>
然后Eater<T>
是T.
逆变我要怎样接口或委托为在其类型参数的协变或逆变?
协变类型参数标记为out
,逆变类型参数标记为in
。
这是为了助记符:协变接口通常在输出位置出现类型参数,并且反向接口有类型参数出现在输入位置。
String
可转换为Object
。我怎样才能让IReadOnlyCollection<String>
兑换成IReadOnlyCollection<Object>
?
请在T.马克它out
IReadOnlyCollection<T>
协变。
考虑下面的代码:
delegate void Action<in T>(T t);
interface IFoo<in X>
{
void M(Action<X> action);
}
为什么编译器说,这是不是有效?
因为它是无效的。让我们看看为什么。
class Foo : IFoo<Fruit>
{
public void M(Action<Fruit> action)
{
action(new Apple()); // An apple is a fruit.
}
}
...
IFoo<Fruit> iff = new Foo();
IFoo<Banana> ifb = iff; // Contravariant!
ifb.M(banana => { banana.Peel(); });
按照逻辑。这个程序通过一个苹果作为Banana.Peel()
的“这个”,这显然是错误的。
编译器知道这可能发生,因此不允许首先声明接口。
我应该怎么做,如果我有变化的问题吗?
您应该先阅读我关于该功能设计和实现的文章。从底部开始;它们列出以相反的顺序为:
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
如果您仍然有问题,那么你应该在这里张贴问题,实际上包含的问题,而不是让人们猜测什么真正的问题是。
顺便提一句,'ItemType'应该叫做'T'。 – SLaks
而不是让'CopyToArray'返回'Array',让它返回'ItemType []',这样它的强类型。 – Servy
这个问题似乎没有任何问题。 “我想要继承工作”不是一个问题。如果你想要一个答案,将其重写为一个问题。编译器是正确的;此代码不是类型安全的。 –