Подтвердить что ты не робот

Почему в классах С# 4.0 нет общей дисперсии?

Если у нас есть это для интерфейсов, почему мы не имеем это также для классов? Какая проблема возникла бы при использовании?

Спасибо

4b9b3361

Ответ 1

Предположим, что у вас был класс C<T>, который был ковариантным в T. Какова может быть его реализация? Т должен быть только. Это означает, что C<T> не может иметь никакого метода, который принимает T, любое свойство типа T с установщиком или любое поле типа T, потому что поля логически совпадают с атрибутами свойств; T входит.

Практически единственная полезная вещь, которую вы могли бы построить с помощью ковариантного класса, - это нечто непреложное, что касается T. Теперь, я думаю, было бы здорово иметь ковариантные непреложные списки и стеки и еще что-то вроде класса. Но эта особенность не настолько очевидна, что она явно оправдывала бы огромные затраты на создание системы типов, которая первоначально поддерживала бы ковариантные неизменные типы классов.

В комментарии выше был приведен пример того, где это было бы полезно. Рассмотрим следующий эскиз:

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

Предположим, что у вас были ковариантные классы. Теперь вы можете сказать

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

И эй, мы просто нажали целое на стопку строк, но все получилось просто отлично! Там нет причин, почему это не может быть типичным. Операция, которая нарушает безопасность типов в изменяемой структуре данных, может быть безопасно ковариантной по неизменной структуре данных.

Ответ 3

Команда .NET вместе с командой С# и VB.NET имеет ограниченные ресурсы, работа, которую они сделали для совместной и контравариантности , решает большую часть проблемы реального мира. Системы типов очень сложны, чтобы получить право - решение, которое работает в 99,9999% случаев, недостаточно хорош, если оно приводит к небезопасному коду в других случаях.

Я не думаю, что стоимость/время поддержки спецификаций co- и contravariance (например, "in" / "out" ) в методах класса имеет достаточно большое значение. Я вижу очень мало случаев, когда они будут полезны - из-за отсутствия многократного наследования классов.

Вы предпочли бы еще 6 месяцев для .net, чтобы получить эту поддержку?


Еще один способ подумать об этом - в .net

  • Интерфейсы/делегаты - используются для моделирования системы концептуального типа приложения
  • Класс используются для реализации указанных выше типов
  • Наследование классов используется для уменьшения дублирования кода при выполнении указанных выше
  • co- и контравариантность относится к концептуальной системе приложения