ReSharper не может найти недоступный код
У меня есть этот код:
Assert.IsTrue(datasetMetadata1 != null && datasetMetadata1.Length == 5);
Assert.IsTrue(datasetMetadata2 != null && datasetMetadata2 .Length == 11);
if ((datasetMetadata1 == null || datasetMetadata1.Length != 5) ||
(datasetMetadata2 == null || datasetMetadata2 .Length != 11)
{
/* do something */
}
который ReSharper упрощает, удаляя лишние (потому что всегда true
) выражение == null
и инвертируя if
Заявление о чем-то похожем на:
if ((datasetMetadataPunktort.Length == 5) && (datasetMetadataFlurstueck.Length == 11))
return
Однако для меня кажется, что даже эта проверка не имеет смысла и может быть легко опущена, поскольку условие всегда выполняется. Поэтому мне интересно, почему ReSharper обнаруживает устаревшую проверку null
но не для остальных.
Я пропускаю какой-либо случай, когда проверка не проходит?
2 ответа
Объяснить мой комментарий:
На мой взгляд, дело в следующем: каждый раз, когда вы проверяете свою ценность, вы звоните получателю. Решарпер не знает, изменяет ли ваш фактический получатель значение или нет. Вполне возможно, что при первом вызове метода получения он возвращает 5 и увеличивает значение на 6. Так что в следующий раз у вас будет 11 возвращено.
Я создал это небольшое консольное приложение в качестве примера:
Этот класс содержит параметр со специальным геттером.
public class TestClass
{
private int _length;
public int Length
{
get
{
var localLength = _length;
_length += 6;
return localLength;
}
set { _length = value; }
}
public TestClass(int length)
{
this._length = length;
}
}
Этот класс используется в целях тестирования:
class Program
{
static void Main(string[] args)
{
var testObject = new TestClass(5);
if ((testObject.Length == 5) && (testObject.Length == 11))
{
Console.WriteLine("TRUE");
}
else
{
Console.WriteLine("FALSE");
}
Console.Read();
}
}
И у нас есть следующий вывод:
TRUE
Я согласен, что этот класс очень особенный, и был сделан с целью заставить условие работать, но все же это показывает, что случай возможен.
В целом, это показывает, что, поскольку метод получения вызывается между каждым условием, значение может изменяться, поэтому вызов не является избыточным.
В дополнение к ответу Висалиевского позвольте мне добавить еще один, еще более простой пример:
int i = 5;
if (i != 5)
{
// do something
}
С помощью этого фрагмента ReSharper не обнаруживает недоступный код.
Но позвольте мне внести небольшое изменение в этот код: сделать меня постоянным.
const int i = 5;
if (i != 5)
{
// do something
}
Теперь ReSharper жалуется на недостижимый код, и я получаю предупреждение компилятора CS0162 в VS2015.
Поэтому при работе с конкретными значениями и ReSharper, и компилятор спрашивают, гарантируется ли значение постоянным или нет. Отсюда я делаю вывод, что эвристика используется с null
и с конкретными значениями разные.