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


102

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'는 사전 조건 검사에만 사용됩니다."


의 선언 및 할당을exceptionMessageif
— AakashM

다음 메서드에서도이 작업을 수행 할 수 있습니다. expectedText + = ""; 메서드에서 사용했기 때문에 불평을 멈 춥니 다.
— PHPGuru 2018

답변:


104

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

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

메서드가 어설 션 메서드이므로 (즉, 유효하다고 ValidateCorrespondingValueType어설 션하는 것뿐입니다) ReSharper의 주석 속성 , 특히 속성을 사용하여을 어설 션 메서드로 표시하여 메시지를 억제 할 수 있습니다 [AssertionMethod].

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

3
좋은 수표이지만 이 경우에는 R #이 약간 초과 도달했습니다. 그렇지 않습니까? settingValue의 유형 에 대한 검사 는 사전 조건이 될 수 없습니다. 검사 대상이 메서드 본문 내에서 일부 작업이 완료 될 때까지 알 수 없기 때문입니다!
— AakashM

6
그렇기 때문에 ReSharper에 어설 션 방법이라고 알려야합니다. 이 방법의 유일한 요점은 다른 방법에 대한 사전 조건 검사를 수행하는 것입니다. 주장이지만 ReSharper는 [AssertionMethod].
— citizenmatt 2014

10
검사 심각도를 "Do Not Show"로 변경했습니다. 이것은 또 다른 옵션입니다.
— reggaeguitar 2014

61
사용하지 않는 정기적 인 매개 변수 검사와는 별도로 '사전 조건 만'검사를 비활성화 할 수 있다면 유용한 기능 일 수 있습니다. 현재 검사는 심각도가 다른 두 가지 문제를 혼합하고 일반적으로 특정 상황에서이 기능을 사용할 수 없게 만듭니다. 또한 소스 코드 분석 도구를 만족스럽게 유지하기 위해 코드에 주석이나 속성을 추가하는 것에 대해 매우 회의적이므로 현재로서는 문제에 대한 만족스러운 해결책이 없다고 생각합니다.
— Serge Belov 2015

7
도움을 주려고 할 수도 있지만 너무 공격적입니다. 이제 값을 확인한 다음 사용하지 않으면 오류 일 수 있습니다. 그러나 오류의 값 만 사용하는 곳에서 나를 비웃고 있습니다. 어떻게 의도적이지 않을 수 있습니까?
— Loren Pechtel

20

흥미롭게도 ReSharper nameof는 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));
    }
}

3
이 응답 정장 나, 그것은 nuget 패키지를 추가하는 것보다 덜 방해입니다
— DanielV

8

다음은 문제를 해결하지만 (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에 의해 반전이 수행됨)가 다른 결과를 제공한다는 것은 흥미 롭습니다. 패턴 매칭은 단순히 두 번째 버전을 선택하지 않는 것 같습니다.


6

이 문제에 대한 내가 선호하는 해결책은 매개 변수 가 사용 되었다고 생각하게 만드는 것 입니다. 이 같은 속성을 사용을 통해 장점을 가지고 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의 확장 메서드 는 네임 스페이스 오염이지만 상당히 포함되어 있습니다.


을 언급하기 위해 +1은 [UsedImplicitly]사용하고 싶지 않았 [AssertionMethod]으며 내 경우에는 암묵적으로 더 정확하게 들립니다 (생성자의 콜백에 값을 전달하고 생성 된 객체를 반환했습니다).
— MrLore

1

다른 사람들은 이미 질문에 대답했지만 아무도 경고를 끄는 다음과 같은 방법을 언급하지 않았습니다.

해당 메서드에 대해서만 해제하려면 메서드 서명 위에 이것을 추가합니다.

    // ReSharper disable once ParameterOnlyUsedForPreconditionCheck.Local

전체 파일에 대해 해제하려면 클래스 선언 위에 이것을 추가하십시오.

     // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local

단점은 의미하는 마녀 매개 변수를 지정할 수 없다는 것입니다.
— comecme

1
@comecme 비활성화를 사용하여 단일 매개 변수에 대해 비활성화하고 해당 특정 매개 변수에 대한 주석을 복원 할 수 있습니다 . 이 경우 모든 매개 변수를 자체 행에 배치하는 것이 좋습니다. 여전히 못 생겼지 만 덜 (내 의견으로는).
— Travis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.