Почему ReSharper судит меня за этот код?
private Control GetCorrespondingInputControl(SupportedType supportedType, object settingValue)
{
this.ValidateCorrespondingValueType(supportedType, settingValue);
switch(supportedType)
{
case SupportedType.String:
return new TextBox { Text = (string)settingValue };
case SupportedType.DateTime:
return new MonthPicker { Value = (DateTime)settingValue, ShowUpDown = true };
default:
throw new ArgumentOutOfRangeException(string.Format("The supported type value, {0} has no corresponding user control defined.", supportedType));
}
}
private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
{
Type type;
switch(supportedType)
{
case SupportedType.String:
type = typeof(string);
break;
case SupportedType.DateTime:
type = typeof(DateTime);
break;
default:
throw new ArgumentOutOfRangeException(string.Format("The supported type value, {0} has no corresponding Type defined.", supportedType));
}
string exceptionMessage = string.Format("The specified setting value is not assignable to the supported type, [{0}].", supportedType);
if(settingValue.GetType() != type)
{
throw new InvalidOperationException(exceptionMessage);
}
}
Параметр "settingValue" второго метода ValidateCorrespondingValueType отображается серым цветом со следующим сообщением от ReSharper: "Параметр 'settingValue' используется только для проверки предварительных условий".
c#
resharper
preconditions
Труп
источник
источник
exceptionMessage
вif
Ответы:
Это не осуждает, а пытается помочь :)
Если ReSharper видит, что параметр используется только для проверки исключения, он выделяет его серым цветом, указывая на то, что вы на самом деле не используете его для «реальной» работы. Скорее всего, это ошибка - зачем передавать параметр, который вы не собираетесь использовать? Обычно это означает, что вы использовали его в предварительном условии, но затем забыли (или больше не нуждаетесь) в его использовании в другом месте кода.
Поскольку метод является методом утверждения (то есть все, что он делает, это утверждает, что он действителен), вы можете подавить сообщение, пометив
ValidateCorrespondingValueType
как метод утверждения, используя атрибуты аннотации ReSharper , в частности[AssertionMethod]
атрибут:источник
settingValue
типа не может быть предварительным условием, так как объект проверки неизвестен до тех пор, пока не будет выполнена некоторая работа в теле метода![AssertionMethod]
.Интересно, что ReSharper отступает, если вы используете новую
nameof
функциональность в C # 6:источник
Следующее устраняет проблему (в ReSharper 2016.1.1, VS2015), но я не уверен, что это решает «правильную» проблему. В любом случае, это показывает неоднозначность механики ReSharper по этой теме:
Это дает предупреждение:
Но это не так:
Интересно, что эквивалентный код (инверсия была сделана ReSharper: D) дает разные результаты. Кажется, что сопоставление с образцом просто не подхватывает вторую версию.
источник
Мое предпочтительное решением этой проблемы является маркой ReSharper думает параметр будет использоваться. Это имеет преимущество по сравнению с использованием атрибута , такого как ,
UsedImplicitly
потому что , если бы вы действительно остановить с помощью этого параметра, ReSharper снова начнет вас предупреждаю. Если вы используете атрибут, resharper также не будет ловить настоящие предупреждения в будущем.Простой способ заставить resharper подумать, что параметр используется, - это заменить
throw
его методом. Так что вместо ......ты пишешь:
Это приятно самодокументируется для будущих программистов, и resharper перестает ныть.
Реализация ThrowPreconditionViolation тривиальна:
Метод расширения Exception - это загрязнение пространства имен, но оно достаточно ограничено.
источник
[UsedImplicitly]
, я не хотел использовать,[AssertionMethod]
поскольку его не было, и используется неявно звучит более точно в моем случае (я передавал значение обратному вызову в конструкторе и возвращал созданный объект).Остальные уже ответили на вопрос, но о следующих способах отключения предупреждения никто не упомянул.
Добавьте это выше сигнатуры метода, чтобы отключить его только для этого метода:
Добавьте это над объявлением класса, чтобы отключить его для всего файла:
источник