Если у нас есть это для интерфейсов, почему мы не имеем это также для классов? Какая проблема возникла бы при использовании?
Спасибо
Если у нас есть это для интерфейсов, почему мы не имеем это также для классов? Какая проблема возникла бы при использовании?
Спасибо
Предположим, что у вас был класс 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);
И эй, мы просто нажали целое на стопку строк, но все получилось просто отлично! Там нет причин, почему это не может быть типичным. Операция, которая нарушает безопасность типов в изменяемой структуре данных, может быть безопасно ковариантной по неизменной структуре данных.
Отметьте это сообщение msdn: Разница в общих типах (Руководство по программированию на С#)
Команда .NET вместе с командой С# и VB.NET имеет ограниченные ресурсы, работа, которую они сделали для совместной и контравариантности , решает большую часть проблемы реального мира. Системы типов очень сложны, чтобы получить право - решение, которое работает в 99,9999% случаев, недостаточно хорош, если оно приводит к небезопасному коду в других случаях.
Я не думаю, что стоимость/время поддержки спецификаций co- и contravariance (например, "in" / "out" ) в методах класса имеет достаточно большое значение. Я вижу очень мало случаев, когда они будут полезны - из-за отсутствия многократного наследования классов.
Вы предпочли бы еще 6 месяцев для .net, чтобы получить эту поддержку?
Еще один способ подумать об этом - в .net