Рассмотрим интерфейс с ковариантным типом T
. Я рассматриваю случай, когда свойства во всех производных классах этого интерфейса, которые используют T
, являются readonly и ковариантными, если общий класс. Предположим, что этот интерфейс затем определяет метод, который использует T
в качестве типа аргумента. Какие нарушения допускаются?Какие нарушения допускают использование ковариантного типа в контравариантной позиции?
Для примера рассмотрим:
interface ICov<out T> {
void maybe_safe_set(T v);
}
class ImplCov<T> : ICov<T> {
public readonly T a;
public readonly IEnumerable<T> b;
public readonly IEnumerable<IEnumerable<T>> c;
// public readonly IList<T> d; // but not this
public void maybe_safe_set(T v) {
// do things that can't modify state: the type of our
// readonly, covariant IEnumerable members can't be modified
}
}
В C#, я получаю ошибку:
Invalid variance: The type parameter 'T' must be contravariantly valid on 'ConsoleApplication.ICov.maybe_safe_set(T)'. 'T' is covariant.
что не удивительно, так как T
находится в контравариантного положении. Однако я не могу думать о нарушении, которое может произойти здесь.
Ковариация означает, что тип потребляется только из интерфейса, никогда не передавался ему. Подумайте об этом таким образом, ключевое слово 'out' означает, что тип должен выйти только из интерфейса, но вы используете его как аргумент метода' maybe_safe_set'. Вместо «T» вместо этого определяется как контравариантная. Интерфейс - это контракт, и он не знает, что может сделать данная реализация. – juharr
'public static class C {public static T Value}' и 'public void maybe_safe_set (T v) {C .Value = v}' и '((ICov
Если это было разрешено, вы могли бы наложить 'ImpleConv' на 'ICov