116

Why is ReSharper judging me for this code?

    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);
        }
    }

The second method ValidateCorrespondingValueType's "settingValue" parameter is grayed out with the following message by ReSharper: "Parameter 'settingValue' is only used for precondition check(s)."

4

7 回答 7

123

这不是判断,而是试图提供帮助:)

如果 ReSharper 发现某个参数仅用作引发异常的检查,它会将其变灰,表明您实际上并未将其用于“真正的”工作。这很可能是一个错误——为什么要传入一个你不会使用的参数?它通常表明您已在前提条件下使用它,但随后忘记(或不再需要)在代码的其他地方使用它。

由于该方法是一个断言方法(也就是说,它所做的只是断言它是有效的),您可以通过ValidateCorrespondingValueType使用 ReSharper 的注释属性(特别是[AssertionMethod]属性)将 标记为断言方法来抑制消息:

[AssertionMethod]
private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
{
  // …
}
于 2014-11-19T11:10:44.877 回答
23

nameof有趣的是,如果您使用C#6 中的新功能,ReSharper 会后退:

static void CheckForNullParameters(IExecutor executor, ILogger logger)
{
    if (executor == null)
    {
        throw new ArgumentNullException(nameof(executor));
    }

    if (logger == null)
    {
        throw new ArgumentNullException(nameof(logger));
    }
}
于 2015-09-25T14:43:49.807 回答
9

以下解决了该问题(在 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)给出了不同的结果。似乎模式匹配根本没有选择第二个版本。

于 2016-05-30T11:34:28.140 回答
6

我对这个问题的首选解决方案是让 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 上的一个扩展方法命名空间污染,但它是相当包含的。

于 2016-02-05T11:12:42.910 回答
3

其他人已经回答了这个问题,但是没有人提到以下关闭警告的方法。

将其添加到方法签名上方以仅针对该方法将其关闭:

    // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local

在类声明上方添加它以关闭整个文件:

     // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local
于 2020-01-29T19:45:30.277 回答
1

我相信下面是一个合法的案例,我用 lambdaAny方法检查列表中的所有项目。然后我在下一行使用相同的方式,但 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();

我不得不忽略评论。

于 2021-03-09T01:53:05.310 回答
-1

在参数上方使用此注释

// ReSharper 禁用一次 ParameterOnlyUsedForPreconditionCheck.Local

在 Rider 中禁用建议

于 2021-07-16T05:54:12.513 回答