public override string ToStringO { return "Это объект класса Alpha.";
}
// ...
}
class Beta : Alpha {
public override string ToStringO { return "Это объект класса Beta.";
}
// ...
}
class VarianceDemo { static void Main {
// Создать ссылку из интерфейса IMyContraVarGenIF
//на объект типа MyClass
// Это вполне допустимо как при наличии контравариантности, так и без нее. IMyContraVarGenIF
// Создать ссылку из интерфейса IMyContraVarGenIF
// на объект типа MyClass
//И это вполне допустимо как при наличии контравариантности,
// так и без нее.
IMyContraVarGenIF
// Создать ссылку из интерфейса IMyContraVarGenIF
//на объект типа MyClass
// *** Это вполне допустимо благодаря контравариантности. *** IMyContraVarGenIF
// Этот вызов допустим как при наличии контравариантности, так и без нее. BetaRef.Show(new Beta);
// Присвоить переменную AlphaRef переменной BetaRef.
// *** Это вполне допустимо благодаря контравариантности. ***
BetaRef = AlphaRef;
BetaRef.Show(new Beta );
}
}
Выполнение этой программы дает следующий результат.
Это объект класса Beta.
Это объект класса Beta.
Контравариантный интерфейс может быть расширен аналогично описанному выше расширению ковариантного интерфейса. Для достижения контравариантного характера расширенного интерфейса в его объявлении должен быть указан такой же параметр обобщенного типа, как и у базового интерфейса, но с ключевым словом in, как показано ниже.
public interface IMyContraVarGenIF2
// ...
}
Следует иметь в виду, что указывать ключевое словоinв объявлении базового интерфейса не только не нужно, но и не допустимо. Более того, сам расширенный интерфейсIMyContraVarGenIF2не обязательно должен быть контравариантным. Иными словами, обобщенный типТв интерфейсеIMyContraVarGenIF2не требуется модифицировать ключевым словомin.Разумеется, все преимущества, которые сулит контравариантность в интерфейсеIMyContraVarGen,при этом будут утрачены в интерфейсеIMyContraVarGenIF2.
Контравариантность оказывается пригодной только для ссылочных типов, а параметр контравариантного типа можно применять только к аргументам методов. Следовательно, ключевое слово in нельзя указывать в параметре типа, используемом в качестве возвращаемого типа.
Вариантные делегаты