Вы не можете этого сделать. Чтобы понять, почему это не разрешено, представьте, что произойдет, если Add
был вызван на List<Derived>
после того, как он был приведен к List<Base>
.
Кроме того, ответы, подразумевающие, что C # 4.0 будет другим, неверны. Список никогда не будет изменен, чтобы позволить вам сделать это. Только IEnumerable
будет - потому что это не позволяет добавлять элементы в коллекцию.
Обновление: причина, по которой это работает в решении, которое вы выбрали, заключается в том, что вы больше не пропускаете тот же список. Вы создаете новый список, который является копией оригинала. Вот почему я спросил об изменении списка; если MethodC
внесет изменения в число элементов в списке, эти изменения будут внесены в копию, а не в исходный список.
Я думаю, что идеальное решение для вас заключается в следующем:
public abstract class A
{
public void MethodC<TItem>(List<TItem> list) where TItem : A
{
foreach (var item in list)
item.CanBeCalled();
}
public abstract void CanBeCalled();
}
public class B : A
{
public override void CanBeCalled()
{
Console.WriteLine("Calling into B");
}
}
class Program
{
static void Main(string[] args)
{
List<B> listOfB = new List<B>();
A a = new B();
a.MethodC(listOfB);
}
}
Обратите внимание, как с помощью этого решения вы можете передать List<B>
непосредственно в MethodC
без необходимости сначала выполнять это странное преобразование. Так что нет необходимости копировать.
Причина, по которой это работает, в том, что мы сказали MethodC
принять список всего, что получено из A
, вместо того, чтобы настаивать на том, что это должен быть список A
.