С# 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.