Resharper는 asp.net 페이지 당 여러 기능을 정적으로 작성할 수있는 기능을 선호합니다. 내가 정적으로 만들면 도움이됩니까? 그것들을 정적으로 만들고 유틸리티 클래스로 옮겨야합니까?
Resharper는 asp.net 페이지 당 여러 기능을 정적으로 작성할 수있는 기능을 선호합니다. 내가 정적으로 만들면 도움이됩니까? 그것들을 정적으로 만들고 유틸리티 클래스로 옮겨야합니까?
답변:
정적 메서드와 인스턴스 메서드
10.2.5 C # 언어 사양의 정적 멤버와 인스턴스 멤버 는 차이점을 설명합니다. 일반적으로 정적 메소드는 인스턴스 메소드에 비해 성능이 약간 향상되지만 다소 극단적 인 상황에서만 가능합니다 (자세한 내용은 이 답변 참조 ).
FxCop 또는 코드 분석 상태의 규칙 CA1822 :
"[멤버를 정적으로 표시] 후에 컴파일러는 각 멤버에 대해 가상이 아닌 호출 사이트를 생성하여 각 호출에 대해 런타임시 현재 오브젝트 포인터가 널이 아닌지 확인하지 못하게합니다. 이로 인해 성능이 크게 향상 될 수 있습니다. 경우에 따라 현재 개체 인스턴스에 액세스하지 못하면 정확성 문제가 발생합니다. "
유틸리티 클래스
디자인에 의미가없는 한 유틸리티 클래스로 이동해서는 안됩니다. 정적 메서드가 ToRadians(double degrees)
각도를 나타내는 클래스 와 관련된 메서드 와 같이 특정 형식과 관련된 경우 해당 메서드가 해당 형식의 정적 멤버로 존재하는 것이 좋습니다 (이는 데모 목적으로 복잡한 예입니다).
성능, 네임 스페이스 오염 등은 모두 제 생각에 부차적입니다. 논리적 인 것이 무엇인지 스스로에게 물어보십시오. 메소드가 유형의 인스턴스에서 논리적으로 작동합니까 아니면 유형 자체와 관련이 있습니까? 후자 인 경우 정적 메서드로 만듭니다. 제어되지 않는 유형과 관련된 경우에만 유틸리티 클래스로 이동하십시오.
인스턴스에 논리적으로 작동하지만 인스턴스 상태를 아직 사용하지 않는 메소드가있는 경우가 있습니다 . 예를 들어, 파일 시스템을 구축 할 때 디렉토리 개념이 있지만 아직 구현하지 않은 경우 파일 시스템 객체의 종류를 반환하는 속성을 작성할 수 있으며 항상 "file"-인스턴스와 논리적으로 관련되어 있으므로 인스턴스 메소드 여야합니다. 메소드를 가상으로 만들려는 경우에도 중요합니다. 특정 구현에는 상태가 필요하지 않지만 파생 클래스는 필요할 수 있습니다. 예를 들어, 컬렉션이 읽기 전용인지 여부를 묻습니다. 해당 컬렉션의 읽기 전용 형식을 아직 구현하지 않았을 수도 있지만 유형이 아닌 컬렉션 자체의 속성입니다.
나는 이것이 당신의 경우에는 일어나지 않을 것이라고 확신하지만, 일부 코드에서 본 하나의 "나쁜 냄새"는 많은 정적 메소드를 사용하여 고통을 겪어야했습니다.
불행하게도, 이들은 특정 애플리케이션 상태를 가정 한 정적 메소드였습니다. (확실히, 우리는 응용 프로그램 당 한 명의 사용자 만 가질 것입니다! User 클래스가 정적 변수에서 그것을 추적하지 않는 이유는 무엇입니까?) 전역 변수에 액세스하는 영광스러운 방법이었습니다. 또한 정적 생성자 (!)가 있었으며 거의 항상 나쁜 생각입니다. (나는 합리적인 예외가 몇 가지 있다는 것을 안다).
그러나 정적 메서드는 실제로 개체 인스턴스의 상태에 의존하지 않는 도메인 논리를 제외 할 때 매우 유용합니다. 코드를 훨씬 더 읽기 쉽게 만들 수 있습니다.
올바른 장소에 배치하십시오. 정적 메소드가 다른 오브젝트의 내부 상태를 방해하지 않고 조작합니까? 그들의 행동이 그 클래스들 중 하나에 속하는 것이 좋은 사례가 될 수 있습니까? 우려 사항을 올바르게 분리하지 않으면 나중에 두통에 걸릴 수 있습니다.
이것은 흥미로운 내용입니다.
http://thecuttingledge.com/?p=57
ReSharper는 실제로 메소드를 정적으로 만들 것을 제안하지 않습니다. 예를 들어 서명에 나타나는 클래스 중 하나와 반대로 해당 메소드가 해당 클래스에있는 이유를 스스로에게 묻어 야합니다.
그러나 여기 resharper documentaion의 내용이 있습니다 : http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static
클래스 내의 복잡한 논리의 경우 인스턴스 입력이 메소드 서명에 명확하게 정의되어 인스턴스 부작용이 발생하지 않는 격리 된 논리를 만드는 데 유용한 전용 정적 메소드를 발견했습니다. 모든 출력은 반환 값 또는 출력 / 참조 매개 변수를 통해 이루어져야합니다. 복잡한 논리를 부작용없이 코드 블록으로 분류 하면 코드의 가독성과 개발 팀의 신뢰도가 향상됩니다.
반면에, 그것은 유틸리티 방법의 확산에 의해 오염 된 클래스로 이어질 수 있습니다. 평소처럼 논리적으로 명명, 문서화 및 팀 코딩 규칙을 일관되게 적용하면이를 완화 할 수 있습니다.
메서드를 정적으로 만들면 먼저 해당 클래스의 인스턴스를 만들지 않고도 클래스 외부에서 메서드를 호출 할 수 있습니다. 이는 타사 공급 업체 개체 또는 애드온으로 작업 할 때 유용합니다. con.Writeline ()을 호출하기 전에 먼저 콘솔 객체 "con"을 만들어야한다고 상상해보십시오.
네임 스페이스 오염을 제어하는 데 도움이됩니다.
Class.a_core_function( .. )
vsa_core_function( .. )
그냥 내 tuppence : 모든 공유 정적 메소드를 유틸리티 클래스에 추가하면 추가 할 수 있습니다
using static className;
코드를 더 빨리 입력하고 읽기 쉽게 만드는 using 문에. 예를 들어, 상속받은 일부 코드에서 "전역 변수"라고하는 것을 많이 가지고 있습니다. 인스턴스 클래스 인 클래스에서 전역 변수를 만들지 않고 전역 변수를 전역 클래스의 정적 속성으로 설정했습니다. 지저분한 경우에는 작업을 수행하며 정적 네임 스페이스가 이미 참조되어 있기 때문에 이름으로 속성을 참조 할 수 있습니다.
이것이 좋은 습관인지 아닌지 전혀 모른다. C # 4/5에 대한 많은 정보와 리팩토링을위한 레거시 코드가 너무 많아서 Roselyn 팁이 나를 안내하도록 노력하고 있습니다.
조이
정적 메소드와 인스턴스 메소드의 차이점을 이미 이해했으면합니다. 또한 긴 답변과 짧은 답변이있을 수 있습니다. 긴 답변은 이미 다른 사람에 의해 제공되었습니다.
내 짧은 대답 : 예, Resharper가 제안하면 정적 메소드로 변환 할 수 있습니다. 그렇게해도 아무런 해가 없습니다. 오히려 메소드를 정적으로 만들면 실제로 메소드를 보호하여 불필요하게 인스턴스 멤버를 해당 메소드에 삽입하지 않습니다. 이런 식으로 OOP 원칙 " 클래스 및 멤버의 액세스 가능성 최소화 "를 달성 할 수 있습니다 .
ReSharper가 인스턴스 메소드를 정적 메소드로 변환 할 수 있다고 제안 할 때 실제로 "왜이 메소드가 상태를 사용하지 않기 때문에이 클래스에 앉아 있는가?" 그래서 그것은 당신에게 생각의 음식을 제공합니다. 그런 다음 해당 메소드를 정적 유틸리티 클래스로 이동해야 할 필요성을 인식 할 수 있습니다. SOLID 원칙에 따라 수업에는 하나의 핵심 책임 만 있어야합니다. 따라서 클래스를 더 잘 정리할 수 있습니다. 때로는 인스턴스 클래스에서도 도우미 메서드가 필요합니다. 이 경우 #region 도우미 내에 유지할 수 있습니다.