为什么 C# 4.0 中的类没有通用差异? [英] Why isn't there generic variance for classes in C# 4.0?

查看:21
本文介绍了为什么 C# 4.0 中的类没有通用差异?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我们有它用于接口,为什么我们也没有它用于类?我们在使用时会遇到什么问题?

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

推荐答案

假设您有一个在 T 中协变的 C 类.它的实现可能是什么样的?T只能出去.这意味着 C 不能有任何接受 T 的方法、任何带有 setter 的 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.

就 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.

这篇关于为什么 C# 4.0 中的类没有通用差异?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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