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.