class A {}
class B : A {}
public void SomeFunction()
{
var someListOfB = new List<B>();
someListOfB.Add(new B());
someListOfB.Add(new B());
someListOfB.Add(new B());
SomeFunctionThatTakesA(someListOfB);
}
public void SomeFunctionThatTakesA(IEnumerable<A> input)
{
// Before C# 4, you couldn't pass in List<B>:
// cannot convert from
// 'System.Collections.Generic.List<ConsoleApplication1.B>' to
// 'System.Collections.Generic.IEnumerable<ConsoleApplication1.A>'
}
В принципе, всякий раз, когда у вас есть функция, которая принимает перечислимый тип одного типа, вы не можете передавать в Enumerable производного типа без явно его литья.
Просто, чтобы предупредить вас о ловушка хотя:
var ListOfB = new List<B>();
if(ListOfB is IEnumerable<A>)
{
// In C# 4, this branch will
// execute...
Console.Write("It is A");
}
else if (ListOfB is IEnumerable<B>)
{
// ...but in C# 3 and earlier,
// this one will execute instead.
Console.Write("It is B");
}
Это ужасный код в любом случае, но он существует, и изменение поведения на C # 4 может привести к тонким и трудным для поиска ошибкам, если вы используете такую конструкцию.