为什么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);
}
}
第二种方法ValidateCorrespondingValueType' s" settingValue" ReSharper使用以下消息将参数灰显为: "参数' settingValue'仅用于前提条件检查。"
答案 0 :(得分:87)
它没有评判,它试图提供帮助:)
如果ReSharper发现某个参数仅用作检查以抛出异常,它会将其灰显,表示您实际上没有将其用于"实际"工作。这很可能是一个错误 - 为什么传递一个你不会使用的参数?它通常表示您已在先决条件下使用它,但后来忘记(或不再需要)在代码中的其他地方使用它。
由于该方法是一个断言方法(也就是说它所做的只是断言它有效),你可以通过使用ReSharper'将ValidateCorrespondingValueType
标记为断言方法来抑制消息。 s annotation attributes,特别是[AssertionMethod]
属性:
[AssertionMethod]
private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
{
// …
}
答案 1 :(得分:12)
有趣的是,如果你在C#6中使用新的nameof
功能,ReSharper会退缩:
static void CheckForNullParameters(IExecutor executor, ILogger logger)
{
if (executor == null)
{
throw new ArgumentNullException(nameof(executor));
}
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
}
答案 2 :(得分:5)
我对此问题的首选解决方案是make resharper认为使用了参数 。这比使用UsedImplicitly
等属性更有优势,因为如果你做停止使用该参数,resharper将再次开始警告你。如果使用属性,resharper也不会捕获未来的真实警告。
使用resharper认为使用参数的一种简单方法是用方法替换throw
。所以不是......
if(myPreconditionParam == wrong)
throw new Exception(...);
...你写道:
if(myPreconditionParam == wrong)
new Exception(...).ThrowPreconditionViolation();
对于未来的程序员来说,这是很好的自我记录,并且resharper退出了抱怨。
ThrowPreconditionViolation的实现很简单:
public static class WorkAroundResharperBugs
{
//NOT [Pure] so resharper shuts up; the aim of this method is to make resharper
//shut up about "Parameter 'Foobaar' is used only for precondition checks"
//optionally: [DebuggerHidden]
public static void ThrowPreconditionViolation(this Exception e)
{
throw e;
}
}
Exception 上的扩展方法是名称空间污染,但它已被公平地包含。
答案 3 :(得分:5)
以下修复了此问题(在ReSharper 2016.1.1,VS2015中),但我不确定它是否解决了“正确”的问题。无论如何,它显示了ReSharper关于这个主题的机制的模糊性:
这会产生警告:
private void CheckForNull(object obj)
{
if (ReferenceEquals(obj, null))
{
throw new Exception();
}
}
但这不是:
private void CheckForNull(object obj)
{
if (!ReferenceEquals(obj, null))
{
return;
}
throw new Exception();
}
有趣的是,等效代码(由ReSharper:D完成的反演)给出了不同的结果。似乎模式匹配根本没有拿起第二个版本。
答案 4 :(得分:2)
其他人已经回答了这个问题,但是没有人提到以下关闭警告的方法。
在方法签名上方添加此代码,以仅针对该方法将其关闭:
// ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local
在类声明上方添加此代码,以针对整个文件将其关闭:
// ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local
答案 5 :(得分:1)
我相信下面是一个合法的案例,我使用 lambda Any
方法检查列表中的所有项目。
然后我在下一行使用相同的方式但是 resharper 失败了。
if (actions.Any(t => t.Id == null)) // here says Paramter t is used only for precondition check(s)
throw new Exception();
actionIds = actions.Select(t => t.Id ?? 0).ToList();
我不得不忽略评论。
答案 6 :(得分:0)
在参数上方使用此注释
<块引用>// ReSharper 禁用一次 ParameterOnlyUsedForPreconditionCheck.Local
在 Rider 中禁用建议