﻿# V3087\. Type of variable enumerated in 'foreach' is not guaranteed to be castable to the type of collection's elements\.

Анализатор обнаружил потенциальную ошибку в цикле 'foreach'\. Существует вероятность возникновения исключения InvalidCastException при обходе коллекции 'IEnumarable<T\>'\.

Рассмотрим пример:

```cpp
List<object> numbers = new List<object>();
....
numbers.Add(1.0);
....
foreach (int a in numbers)
  Console.WriteLine(a);
```

В данном случае, шаблон коллекции 'numbers' инициализирован типом 'object', тем самым позволяя добавлять в неё объекты любого типа\.

При обходе этой коллекцией, в цикле задано, что её члены должны иметь тип 'int'\. Если в коллекции окажется объект другого типа, будет выполнено приведение и возможно возникновение исключения 'InvalidCastException'\. В нашем примере исключение возникнет из\-за невозможности распаковки \(Unboxing\) значения типа 'double', упакованного в элементе типа 'object' коллекции, в тип 'int'\.

Для исправления данной ошибки можно привести тип шаблона коллекции и тип элемента в цикле 'foreach' к одному типу:

Вариант 1:

```cpp
List<object> numbers = new List<object>();
....
foreach (object a in numbers)
```

Вариант 2:

```cpp
List<int> numbers = new List<int>();
....
foreach (int a in numbers)
```

Часто подобная ошибка наблюдается, когда имеется коллекция с элементами базового интерфейса, а в цикле указывают тип одного из интерфейсов или классов, реализующих данный базовый интерфейс:

```cpp
void Foo1(List<ITrigger> triggers){
  ....
  foreach (IOperableTrigger trigger in triggers)
  ....
}
void Foo2(List<ITrigger> triggers){
  ....
  foreach (IMutableTrigger trigger in triggers)
  ....
}
```

Для обхода в коллекции объектов только одного конкретного типа, можно предварительно отфильтровать её с помощью функции 'OfType':

```cpp
void Foo1(List<ITrigger> triggers){
  ....
  foreach (IOperableTrigger trigger in
    triggers.OfType<IOperableTrigger>())
  ....
}
void Foo2(List<ITrigger> triggers){
  ....
  foreach (IMutableTrigger trigger in 
    triggers.OfType<IMutableTrigger>())
  ....
}
```

Такой код гарантирует, что цикл foreach будет работать только с объектами нужного типа, и исключит возможность возникновения исключения 'InvalidCastException'\.