V3102. Suspicious access to element by a constant index inside a loop.
Анализатор обнаружил возможную ошибку, связанную с тем, что в цикле 'for' на каждой итерации к элементу массива или списка обращаются по одному и тому же константному индексу.
Рассмотрим пример некорректного кода:
ParameterInfo[] parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
Type parameterType = parameters[0].ParameterType;
....
}
Здесь на каждой итерации цикла планировали сохранять некое значение i-го элемента массива 'parameters' в переменную 'parameterType', но допустили опечатку, и на каждой итерации работают с одним и тем же - первым - элементом массива. Возможно также, что при написании кода программист отлаживался с использованием нулевого элемента, а потом забыл изменить значение индекса.
Корректный вариант кода:
ParameterInfo[] parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
Type parameterType = parameters[i].ParameterType;
....
}
Рассмотрим ещё один пример с ошибкой, взятый из реального приложения:
if (method != null && method.SequencePoints.Count > 0)
{
CodeCoverageSequence firstSequence = method.SequencePoints[0];
int line = firstSequence.Line;
int column = firstSequence.Column;
for (int i = 1; i < method.SequencePoints.Count; ++i)
{
CodeCoverageSequence sequencePoint = method.SequencePoints[0];
if (line > sequencePoint.Line)
{
line = sequencePoint.Line;
column = sequencePoint.Column;
}
}
// ....
}
В этом фрагменте кода разработчик реализовал отдельную обработку нулевого элемента списка 'method.SequencePoints', а обход остальных элементов сделал в цикле. К сожалению, программист скопировал в тело цикла строку с доступом к нулевому элементу и переименовал только имя переменной с 'firstSequence' на 'sequencePoint', а изменить индекс забыл.
Корректный вариант кода:
if (method != null && method.SequencePoints.Count > 0)
{
CodeCoverageSequence firstSequence = method.SequencePoints[0];
int line = firstSequence.Line;
int column = firstSequence.Column;
for (int i = 1; i < method.SequencePoints.Count; ++i)
{
CodeCoverageSequence sequencePoint = method.SequencePoints[i];
if (line > sequencePoint.Line)
{
line = sequencePoint.Line;
column = sequencePoint.Column;
}
}
// ....
}
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3102. |