Это можно сделать только в том случае, если вы объявили интерфейс как имеющий ковариантный (out
) параметр. Это можно сделать только в том случае, если параметр используется ковариантно.
Например, если в интерфейсе IMyGenericObject<T>
есть метод, принимающий параметр T
, это препятствует объявлению параметра ковариантным. И наоборот, если есть метод, который возвращает T
, который не позволяет вам объявить параметр как контравариантный.
EDIT
В ответ на ваш комментарий к ответу SLaks я испытываю желание повторить все, что Эрик Липперт когда-либо писал о совместной и контрвариантности. См. http://blogs.msdn.com/b/ericlippert/archive/tags/Covariance+and+Contravariance/, а также его ответы в SO (совсем недавно https://stackoverflow.com/a/8380213/385844)
Подведем итог:
Вы не можете разыграть IList<string>
на IList<object>
, потому что законно передавать FileInfo
на IList<object>
, но недопустимо передавать его на IList<string>
.
Вы не можете привести IList<object>
к IList<string>
, потому что законно извлечь элемент из IList<string>
и назначить его для ссылки на строку, но IList<object>
может содержать FileInfo, который может не может быть привязан к строковой ссылке.
РЕДАКТИРОВАТЬ 2
Поскольку вы обратились за советом, также возможно разделить ваши интерфейсы на ко-и контравариантные части. Чтобы продолжить с примером списка, вы могли бы иметь эти интерфейсы
public interface ICovariantList<out T>
{
T this[int index] { get; }
//...
}
public interface IContravariantList<in T>
{
T this[int index] { set; }
void Add(T item);
//...
}
public class SomeList<T> : ICovariantList<T>, IContravariantList<T>
{
//...
}
Это позволяет использовать класс ковариантно или контравариантно, в зависимости от контекста.