Нет, C # 3 не поддерживает универсальную дисперсию .C # 4 делает, но вы должны объявить, что IStatisticsRepository
является ковариантным в T
:
public interface IStatististicsRepository<out T> : IRepository<T>
where T : IStastistic
Дисперсия небезопасна в общем - это зависит от того, как универсальныйПараметр типа используется.C # 4 поддерживает как ковариацию, так и контравариантность для аргументов типа, которые являются ссылочными типами, но только тогда, когда задействованный универсальный тип является интерфейсом или делегатом, и только когда параметр типа используется соответствующим образом в интерфейсе / делегате.
Не видя декларации для IRepository<T>
, мы не можем сказать, безопасно ли это.Например, если IRepository<T>
содержит такой метод:
void Save(string id, T value);
, тогда не будет безопасным, потому что вы сможете написать:
IStatisticsRepository<IStatistic> repo = RepositoryFactory.AverageCheckTimeRepository;
IStatistic foo = new SomeOtherStastisticType();
repo.Save("Foo", foo);
Это будет попытка сохранить значение SomeOtherStatisticType
в AverageCheckTimeRepository
, что нарушает безопасность типов.Ковариантность интерфейса можно сделать только в T
, только если значения типа T
выходят только из интерфейса.(Есть некоторые морщины вокруг именно того, что это значит, заметьте ...)
Для получения дополнительной информации об этом см. Серию блогов Эрика Липперта на тему .