为什么没有为类在C#4.0泛型方差?方差

2023-09-02 10:17:02 作者:幸福不在遥远

如果我们把它的接口,为什么不我们还上课?会是什么,我们会在使用时incurr问题?

If we have it for interfaces, why dont we have it also for classes? What would be the problem that we would incurr when using it?

感谢

推荐答案

假设你有一个类 C< T> 这是协变的T.什么可能的实施看喜欢? T有被淘汰而已。这意味着, C< T> 不能接受一个T,T型的任何财产与二传手的任何方法,或类型T的任意字段,因为域在逻辑上是一样的属性设置器; t趋于研究。

Suppose you had a class C<T> that was covariant in T. What might its implementation look like? T has to be out only. That means that C<T> cannot have any method that takes a T, any property of type T with a setter, or any field of type T, because fields are logically the same as property setters; T goes in.

pretty的大部分唯一有用的东西是永恒不变的东西尽可能T被关注。现在,我认为这将是真棒有协变不变的列表和堆栈和诸如此类的东西那是类类型。但是,该功能并不是那么明显真棒,这显然证明在使类型系统原生支持协变的不可变的类类型的大规模支出。

Pretty much the only useful thing you could build with a covariant class is something immutable as far as T is concerned. Now, I think it would be awesome to have covariant immutable lists and stacks and whatnot that were class types. But that feature is not so obviously awesome that it would clearly justify the massive expenditure in making the type system natively support covariant immutable class types.

注释上述要求的,但这样做是有用的一个例子。考虑下面的草图:

A comment above asked for an example of where this would be useful. Consider the following sketch:

sealed class Stack<out T>
{
    private readonly T head;
    private readonly Stack<T> tail;
    public T Peek() { return head; }
    public Stack<T> Pop() { return tail; }
    public Stack(T head, Stack<T> tail)
    {
        this.tail = tail;
        this.head = head;
    }
}
static class StackExtensions
{
    public static Stack<T> Push<T>(this Stack<T> tail, T head) 
    {
        return new Stack<T>(head, tail);
    }
    public static bool IsEmpty<T>(this Stack<T> stack)
    {
        return stack == null;
    }
}

假设你有协类。现在,你可以说

Suppose you had covariant classes. Now you can say

Stack<string> strings = null;
strings = strings.Push("hello");
strings = strings.Push("goodbye");
Stack<object> objects = strings;
objects = objects.Push(123);

和嘿,我们只是把一个整数入栈字符串,但一切工作就好了!没有理由,为什么这可能不会是类型安全。这将违背一个可变数据结构类型安全的操作可以安全协变的不可变的数据结构。

And hey, we just pushed an integer onto a stack of strings, but everything worked out just fine! There's no reason why this couldn't be typesafe. An operation which would violate type safety on a mutable data structure can be safely covariant on an immutable data structure.