program tip

ReSharper Curiosity : "매개 변수는 전제 조건 확인에만 사용됩니다."

radiobox 2020. 9. 8. 07:51
반응형

ReSharper Curiosity : "매개 변수는 전제 조건 확인에만 사용됩니다."


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의 "settingValue"매개 변수는 ReSharper에서 다음 메시지와 함께 회색으로 표시됩니다. "Parameter 'settingValue'는 사전 조건 검사에만 사용됩니다."


판단하는 것이 아니라 도움을 주려는 것입니다. :)

ReSharper에서 매개 변수가 예외를 발생시키기위한 검사로만 사용되는 것을 확인하면이를 회색으로 표시하여 실제로 "실제"작업에 사용하고 있지 않음을 나타냅니다. 이것은 실수 일 가능성이 큽니다. 사용하지 않을 매개 변수를 전달하는 이유는 무엇입니까? 일반적으로 사전 조건에서 사용했지만 코드의 다른 곳에서 사용하는 것을 잊었거나 더 이상 사용할 필요가 없음을 나타냅니다.

Since the method is an assertion method (that is, all it does is assert it's valid), you can suppress the message by marking the ValidateCorrespondingValueType as an assertion method, using ReSharper's annotation attributes, specifically the [AssertionMethod] attribute:

[AssertionMethod]
private void ValidateCorrespondingValueType(SupportedType supportedType, object settingValue)
{
  // …
}

Interestingly, ReSharper backs off if you use the new nameof functionality in C#6:

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

    if (logger == null)
    {
        throw new ArgumentNullException(nameof(logger));
    }
}

My preferred solution to this problem is make resharper think the parameter is used. This has an advantage over using an attribute such as UsedImplicitly because if ever you do stop using that parameter, resharper will start warning you again. If you use an attribute, resharper won't catch future real warnings either.

An easy way to make resharper think the paramter is used is by replacing throw with a method. So instead of...

if(myPreconditionParam == wrong)
    throw new Exception(...);

...you write:

if(myPreconditionParam == wrong)
    new Exception(...).ThrowPreconditionViolation();

This is nicely self-documenting for future programmers, and resharper quits whining.

The implementation of ThrowPreconditionViolation is trivial:

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

An extension method on Exception is namespace pollution, but it's fairly contained.


The following fixes the issue (in ReSharper 2016.1.1, VS2015), but I am not sure it solves the 'right' problem. In any case, it shows the ambiguity in ReSharper's mechanics regarding this topic:

This yields the warning:

    private void CheckForNull(object obj)
    {
        if (ReferenceEquals(obj, null))
        {
            throw new Exception();
        }
    }

But this does not:

    private void CheckForNull(object obj)
    {
        if (!ReferenceEquals(obj, null))
        {
            return;
        }
        throw new Exception();
    }

It is interesting that equivalent code (the inversion was done by ReSharper :D) gives different results. It seems that the pattern matching simply does not pick up the second version.

참고URL : https://stackoverflow.com/questions/27010269/resharper-curiosity-parameter-is-only-used-for-precondition-checks

반응형