[C#] 메소드를 정적으로 만들 수는 있지만 그렇게해야합니까?

Resharper는 asp.net 페이지 당 여러 기능을 정적으로 작성할 수있는 기능을 선호합니다. 내가 정적으로 만들면 도움이됩니까? 그것들을 정적으로 만들고 유틸리티 클래스로 옮겨야합니까?



답변

정적 메서드와 인스턴스 메서드

10.2.5 C # 언어 사양의 정적 멤버와 인스턴스 멤버 는 차이점을 설명합니다. 일반적으로 정적 메소드는 인스턴스 메소드에 비해 성능이 약간 향상되지만 다소 극단적 인 상황에서만 가능합니다 (자세한 내용은 이 답변 참조 ).

FxCop 또는 코드 분석 상태의 규칙 CA1822 :

“[멤버를 정적으로 표시] 후에 컴파일러는 각 멤버에 대해 가상이 아닌 호출 사이트를 생성하여 각 호출에 대해 런타임시 현재 오브젝트 포인터가 널이 아닌지 확인하지 못하게합니다. 이로 인해 성능이 크게 향상 될 수 있습니다. 경우에 따라 현재 개체 인스턴스에 액세스하지 못하면 정확성 문제가 발생합니다. “

유틸리티 클래스
디자인에 의미가없는 한 유틸리티 클래스로 이동해서는 안됩니다. 정적 메서드가 ToRadians(double degrees)각도를 나타내는 클래스 와 관련된 메서드 와 같이 특정 형식과 관련된 경우 해당 메서드가 해당 형식의 정적 멤버로 존재하는 것이 좋습니다 (이는 데모 목적으로 복잡한 예입니다).


답변

성능, 네임 스페이스 오염 등은 모두 제 생각에 부차적입니다. 논리적 인 것이 무엇인지 스스로에게 물어보십시오. 메소드가 유형의 인스턴스에서 논리적으로 작동합니까 아니면 유형 자체와 관련이 있습니까? 후자 인 경우 정적 메서드로 만듭니다. 제어되지 않는 유형과 관련된 경우에만 유틸리티 클래스로 이동하십시오.

인스턴스에 논리적으로 작동하지만 인스턴스 상태를 아직 사용하지 않는 메소드가있는 경우가 있습니다 . 예를 들어, 파일 시스템을 구축 할 때 디렉토리 개념이 있지만 아직 구현하지 않은 경우 파일 시스템 객체의 종류를 반환하는 속성을 작성할 수 있으며 항상 “file”-인스턴스와 논리적으로 관련되어 있으므로 인스턴스 메소드 여야합니다. 메소드를 가상으로 만들려는 경우에도 중요합니다. 특정 구현에는 상태가 필요하지 않지만 파생 클래스는 필요할 수 있습니다. 예를 들어, 컬렉션이 읽기 전용인지 여부를 묻습니다. 해당 컬렉션의 읽기 전용 형식을 아직 구현하지 않았을 수도 있지만 유형이 아닌 컬렉션 자체의 속성입니다.


답변

static클래스 내 에서 메소드를 표시하면 인스턴스 멤버를 사용하지 않는 것이 분명하므로 코드를 통해 스키밍 할 때 알아두면 도움이됩니다.

개념적으로 밀접하게 연결된 다른 클래스와 공유하지 않는 한 반드시 다른 클래스로 옮길 필요는 없습니다.


답변

나는 이것이 당신의 경우에는 일어나지 않을 것이라고 확신하지만, 일부 코드에서 본 하나의 “나쁜 냄새”는 많은 정적 메소드를 사용하여 고통을 겪어야했습니다.

불행하게도, 이들은 특정 애플리케이션 상태를 가정 한 정적 메소드였습니다. (확실히, 우리는 응용 프로그램 당 한 명의 사용자 만 가질 것입니다! User 클래스가 정적 변수에서 그것을 추적하지 않는 이유는 무엇입니까?) 전역 변수에 액세스하는 영광스러운 방법이었습니다. 또한 정적 생성자 (!)가 있었으며 거의 ​​항상 나쁜 생각입니다. (나는 합리적인 예외가 몇 가지 있다는 것을 안다).

그러나 정적 메서드는 실제로 개체 인스턴스의 상태에 의존하지 않는 도메인 논리를 제외 할 때 매우 유용합니다. 코드를 훨씬 더 읽기 쉽게 만들 수 있습니다.

올바른 장소에 배치하십시오. 정적 메소드가 다른 오브젝트의 내부 상태를 방해하지 않고 조작합니까? 그들의 행동이 그 클래스들 중 하나에 속하는 것이 좋은 사례가 될 수 있습니까? 우려 사항을 올바르게 분리하지 않으면 나중에 두통에 걸릴 수 있습니다.


답변

이것은 흥미로운 내용입니다.

http://thecuttingledge.com/?p=57

ReSharper는 실제로 메소드를 정적으로 만들 것을 제안하지 않습니다. 예를 들어 서명에 나타나는 클래스 중 하나와 반대로 해당 메소드가 해당 클래스에있는 이유를 스스로에게 묻어 야합니다.

그러나 여기 resharper documentaion의 내용이 있습니다 :
http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static


답변

@Jason True의 답변 에 추가하기 위해 메소드에 ‘정적’을 적용한다고해서 메소드가 ‘순수’하다는 것을 보장하지는 않습니다. 선언 된 클래스와 관련하여 상태가 없지만 상태가있는 다른 ‘정적’객체 (응용 프로그램 구성 등)에 잘 액세스 할 수 있습니다. 이것은 항상 나쁜 것은 아니지만 그 이유 중 하나입니다. 나는 개인적으로 정적 메소드를 선호하는 경향이 있습니다. 순결한 메소드는 순수하면 주변 상태에 대해 걱정할 필요없이 테스트하고 격리 할 수 ​​있다는 것입니다.


답변

주어진 시나리오에서 가장 읽기 쉽고 직관적 인 작업을 수행해야합니다.

실제로 일어나고있는 유일한 것은 하나의 추가 매개 변수 ( this)가 인스턴스 메소드의 스택으로 푸시되는 것이므로 가장 극단적 인 상황을 제외하고는 성능 인수가 좋지 않습니다 .