С# foreach поведение с производными классами?

Сейчас у меня есть относительно простая установка класса:

class A{
//stuff
}
class B:A{
//more stuff
}
public List<A> ListOfObjects;

Что произойдет, если я сделаю

foreach(B i in ListOfObjects)

Я бы получил только объекты типа B? Применит ли он магию OO и преобразует все как в B? Будет ли это работать?

Ответ 1

Если в списке есть A (или другие вещи, которые не являются B или подклассами B), тогда он просто сломается с недопустимым литьем. Вероятно, вы хотите:

foreach(B i in ListOfObjects.OfType<B>()) {...}

в .NET 3.5. (Я предполагаю, что сам список будет непустым, btw)

Ответ 2

Я лично использую var как переменную цикла в foreach при любых обстоятельствах, чтобы избежать любой возможности недействительного выполнения. Таким образом, тип переменной цикла будет статическим типом элементов коллекции; если вы хотите что-то другое, используйте OfType для выполнения безопасного фильтра.

Еще несколько объяснений здесь.

Ответ 3

foreach перечисляет все объекты в коллекции. Если тип выполнения элемента несовместим с типом переменной итератора (в вашем случае я типа B) генерируется исключение TypeCasException.

Вместо этого вы можете сделать это:

foreach(A i in ListOfObjects)
{
   B b = i as B
   if (b!=null) ..
}

Или вы можете отфильтровать список перед его итерацией. Простейшим решением будет запрос linq.