developer tip

ReSharper는 메서드가 정적 일 수 있지만 그렇지 않은 경우 불평합니다.

optionbox 2020. 11. 17. 08:01
반응형

ReSharper는 메서드가 정적 일 수 있지만 그렇지 않은 경우 불평합니다.


메서드가 정적으로 될 수 있지만 그렇지 않은 경우 ReSharper가 불평하는 이유는 무엇입니까?

유형에 대해 정적 메서드의 인스턴스가 하나만 생성되어 성능이 절약되기 때문입니까?


나는 그 주석이 두 가지 중요한 점을 지적하기 때문에 매우 유용하다고 생각합니다.

  1. 문제의 방법이 실제로 유형의 일부 여야하는지 스스로에게 묻게합니다. 인스턴스 데이터를 사용하지 않으므로 최소한 자체 유형으로 이동할 수 있는지 고려해야합니다. 유형의 필수 부분입니까, 아니면 실제로 범용 유틸리티 방법입니까?

  2. 메서드를 특정 형식으로 유지하는 것이 합리적이면 컴파일러가 정적 메서드에 대해 다른 코드를 방출하므로 잠재적 인 성능 향상이 있습니다.


동일한 경고에 대한 FxCop 문서에서 (강조 추가됨) :

"인스턴스 데이터에 액세스하지 않거나 인스턴스 메서드를 호출하지 않는 멤버는 정적으로 표시 될 수 있습니다 (Visual Basic에서 공유 됨). 메서드를 정적으로 표시하면 컴파일러가 이러한 멤버에 대해 비가 상 호출 사이트를 내 보냅니다. 비가 상 호출을 내 보냅니다. 사이트는 현재 개체 포인터가 null 아닌지 확인하는 각 호출에 대해 런타임시 검사를 방지합니다. 이로 인해 성능에 민감한 코드에 대해 측정 가능한 성능 향상이 발생할 수 있습니다. 경우에 따라 현재 개체 인스턴스에 액세스하지 못하는 경우 정확성 문제. "


여기에 그 주제에 대한 아주 좋은 토론이 있습니다 (SO) . 나는 정적으로 만들 수 있다면 정적으로 만들 수있는 캠프에있다. 나는 인스턴스 데이터를 사용하지 않는 인스턴스 메서드를 갖는 이유에 대한 개념 때문이라고 생각합니다. 이 경우 실제로 인스턴스 메서드입니까 아니면 실제로 클래스 메서드입니까?


메서드가 static으로 선언 된 경우 메서드를 사용하기 위해 클래스의 인스턴스를 생성 할 필요가 없습니다.이 메서드는 구성 처리에 필요한 CPU주기, 힙 공간 및 가비지 수집기에서 개체를 회수 할 때 CPU주기를 절약합니다. 더미...

또한 귀하의 질문은

"... 정적 메서드의 인스턴스가 하나만 생성됩니다 (유형에서) ..."

인스턴스 메서드의 경우 생성 된 클래스의 각 인스턴스에 대해 메서드에 대한 코드가 반복됨을 의미합니다. 그것은 사실이 아닙니다. 어떤 유형에 대해 생성 한 인스턴스 수에 관계없이 메서드에 대한 코드는 메모리에 한 번만로드됩니다. 각 인스턴스의 힙에 저장된 객체는 유형의 "상태"(비 정적 필드 및 몇 가지 기타 추적 변수) 만 저장합니다.


불만이 아니라 조언 일뿐입니다.


정적 메서드를 위해 함수 스택에 "this"를 푸시 할 필요가 없습니다. 그것이 더 저렴한 또 다른 이유입니다.


저에게는이 ReSharper 조언의 가장 큰 이점입니다 (경고, 제안 또는 힌트로 설정할 수 있음). 가능한 한 많은 메서드를 정적으로 만들도록 권장한다는 것입니다. 정적 메서드는 자신이 속한 클래스에 대한 직접적인 종속성이 없기 때문에 이것은 좋은 일입니다. 즉, 정적 멤버로 다른 클래스로 쉽게 이동할 수 있습니다.

ReSharper에서 정적을 사용하는 또 다른 트릭은 "메서드 정적 만들기"리팩토링을 사용하여 관련 메소드 세트를 정적으로 만드는 것입니다. 이렇게하면 일부 종속성이 메서드 매개 변수로 이동합니다. 나중에이 메소드 세트를 살펴보면 모두 특정 유형의 특정 객체에 액세스한다는 것을 알 수 있습니다. 그런 다음 "Make method non-static"리팩토링을 사용하고 해당 객체를 새 this 포인터 로 지정할 수 있습니다. 그러면 메서드가 다른 클래스로 이동합니다.

이것으로부터:

internal class ClassA
{
    public ClassB Property { get; set; }

    public int Method()
    {
        var classB = Property;
        return classB.Property1 + classB.Property2;
    }
}

internal class ClassB
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

이에:

    public static int Method(ClassB property)
    {
        var classB = property;
        return classB.Property1 + classB.Property2;
    }

이에:

internal class ClassA
{
    public ClassB Property { get; set; }
}

internal class ClassB
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }

    public int Method()
    {
        return Property1 + Property2;
    }
}

정적은 처음 사용할 때 인스턴스화되고 메모리에 남아 있습니다. 더 이상 사용되지 않으면 문제가 될 수 있습니다. 정전기는 테스트하기가 더 어렵습니다 (모크 등).

참고 URL : https://stackoverflow.com/questions/790281/resharper-complains-when-method-can-be-static-but-isnt

반응형