C#通用继承和协方差第2部分 [英] C# generic inheritance and covariance part 2

查看:56
本文介绍了C#通用继承和协方差第2部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的原始主题: C#通用继承和协变

仅在我的只读接口上,我希望继承起作用.

On just my read-only interfaces, I want inheritence to work.

public delegate Boolean EnumerateItemsDelegate<out ItemType>(ItemType item);

public interface IReadOnlyCollection<out ItemType>
{
    Boolean ContainsItem(ItemType item);
    Array CopyToArray();
    void EnumerateItems(EnumerateItemsDelegate<ItemType> enumerateDelegate);

    UInt32 Count { get; }
    UInt32 Capacity { get; }
}

就像这样,除了编译位置:-p

Like this except where it compiles :-p

这就是我要工作的:

IReadOnlyCollection<String> s;
IReadOnlyCollection<Object> o = s;

推荐答案

这个问题似乎没有任何问题,所以我将回答几个问题.

There does not appear to be any question in this question, so I'll make up a few questions to answer.

什么是协变转换?

What is a covariant conversion?

假设我们有一些类型的 Fruit Apple Banana 具有明显的关系; Apple 是一种 Fruit ,以此类推.

Let's suppose we have some types Fruit and Apple and Banana with the obvious relationships; Apple is a kind of Fruit, and so on.

协变转换是类型参数的可转换性暗示泛型类型的可转换性的转换.如果 Apple 可转换为 Fruit ,并且 Bowl< Apple> 可转换为 Bowl< Fruit> ,则 Bowl< T> 在T中是协变的.

A covariant conversion is one where the convertability of the type argument implies the convertibility of the generic type. If Apple is convertible to Fruit, and Bowl<Apple> is convertible to Bowl<Fruit>, then Bowl<T> is covariant in T.

什么是逆转换?

逆变转换是一种协变转换,它反转方向而不是保留方向.如果 Eater< Fruit> 可转换为 Eater< Apple> ,则 Eater< T> 在T中是互变的.

A contravariant conversion is a covariant conversion that reverses the direction instead of preserving it. If Eater<Fruit> is convertible to Eater<Apple> then Eater<T> is contravariant in T.

如何在接口或委托的类型参数中将其标记为协变或相反?

How do I mark an interface or delegate as being covariant or contravariant in its type parameters?

协变量类型参数标记为 out ,而协变量类型参数标记为 in .

Covariant type parameters are marked out and contravariant type parameters are marked in.

这旨在用作助记符:协变接口通常将类型参数显示在输出位置,而互变接口通常将类型参数显示在输入位置.

This is intended to be mnemonic: covariant interfaces typically have the type parameter appear in output positions and contravariant interfaces typeically have the type parameter appear in input positions.

String 可转换为 Object .如何使 IReadOnlyCollection< String> 可转换为 IReadOnlyCollection< Object> ?

String is convertible to Object. How can I make IReadOnlyCollection<String> convertible to IReadOnlyCollection<Object>?

在T中使 IReadOnlyCollection< T> 协变.将其标记为 out .

Make IReadOnlyCollection<T> covariant in T. Mark it out.

考虑以下代码:

delegate void Action<in T>(T t);
interface IFoo<in X>
{
  void M(Action<X> action);
}

为什么编译器说这是无效的?

Why does the compiler say that this is not valid?

因为它无效.让我们看看为什么.

Because it is not valid. Let's see why.

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()的"this"传递,这显然是错误的.

Follow the logic. This program passes an apple as the "this" of Banana.Peel(), which is clearly wrong.

编译器知道这是可能发生的,因此不允许首先声明接口.

The compiler knows that this can happen, and so disallows the interface to be declared in the first place.

如果我还有更多关于方差的问题怎么办?

What should I do if I have more questions about variance?

您应该先阅读有关该功能的设计和实现的文章.从底部开始;它们以相反的时间顺序列出:

You should start by reading my articles on the design and implementation of the feature. Start from the bottom; they are listed in reverse chronological order:

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance + and + contravariance/

如果您仍然有问题,则应在此处发布实际上包含问题的问题,而不是让人们猜测问题的实质.

If you still have a question then you should post questions here that actually contain questions, instead of making people guess what the question really is.

这篇关于C#通用继承和协方差第2部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆