本文介绍了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.

假设我们有一些类型的 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.

协变量类型参数标记为 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.

在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);
}

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

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.

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

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部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 04:32