Я передаю приведенный результат в функцию, которая принимает IList<Derived>
.
Тогда вы находитесь в мире боли, которую вы сами изобрели. Мой совет был бы первым, чтобы найти какой-то другой способ решить вашу проблему круговой зависимости. Как вы обнаружили, превращение всего в интерфейсы, которые имеют только одну возможную реализацию, является болезненным способом решения этой проблемы. Я не рекомендую это.
Если вы не можете этого сделать, то я бы попытался исправить функцию, которая нарушает работу, чтобы она либо принимала IList<IBase>
, IEnumerable<IBase>
или IEnumerable<Derived>
. Предпочтительно одно из множества решений; большинство методов, которые принимают списки , на самом деле нуждаются только в последовательностях . Если бы вы могли объяснить, зачем вам нужен этот список, это поможет найти обходной путь.
Если вы можете сделать это, взяв IList<IBase>
или IEnumerable<IBase>
, тогда все готово; у вас уже есть что-то, что неявно преобразуется в нужный тип.
Если вы можете заставить его принять IEnumerable<Derived>
, тогда вы можете сказать myListOfIBase.Cast<Derived>()
(если вы действительно знаете, что все они являются производными) или myListOfIBase.OfType<Derived>()
(если вы подозреваете, что некоторые из них могут не относиться к типу Derived и хотите их пропустить) и получите IEnumerable<Derived>
, который эффективно использует базовый список.
Если вы не можете изменить функцию-нарушитель, тогда вы можете создать свой собственный класс, который эффективно использует базовый список:
sealed class MyProxyList : IList<Derived>
{
IList<IBase> underlyingList;
public MyProxyList(IList<IBase> underlyingList)
{
this.underlyingList = underlyingList;
}
... now implement every member of IList<Derived> as
... a call to underlyingList with a cast where necessary
}
А затем передайте новый MyProxyList
методу.