Анализатор обнаружил потенциальную ошибку в цикле '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. |