Анализатор обнаружил потенциальную ошибку в цикле 'foreach'. Существует вероятность возникновения исключения InvalidCastException при обходе коллекции 'IEnumarable<T>'.
Рассмотрим пример:
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:
List<object> numbers = new List<object>(); .... foreach (object a in numbers)
Вариант 2:
List<int> numbers = new List<int>(); .... foreach (int a in numbers)
Часто подобная ошибка наблюдается, когда имеется коллекция с элементами базового интерфейса, а в цикле указывают тип одного из интерфейсов или классов, реализующих данный базовый интерфейс:
void Foo1(List<ITrigger> triggers){ .... foreach (IOperableTrigger trigger in triggers) .... } void Foo2(List<ITrigger> triggers){ .... foreach (IMutableTrigger trigger in triggers) .... }
Для обхода в коллекции объектов только одного конкретного типа, можно предварительно отфильтровать её с помощью функции 'OfType':
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'.
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3087. |