.Net 프레임 워크에서 대량의 봉인 된 클래스 뒤에있는 동기가 무엇인지 듣고 싶습니다. 클래스 봉인의 이점은 무엇입니까? 상속을 허용하지 않는 것이 얼마나 유용한 지, 그리고 이러한 클래스와 싸우는 유일한 사람이 아닐 가능성이 큽니다.
그렇다면 프레임 워크가 이러한 방식으로 설계된 이유는 무엇이며 모든 것을 개봉하는 데있어 확연한 변화가 아닐까요? 또 다른 이유가 있겠지만 그저 악한 것입니까?
.Net 프레임 워크에서 대량의 봉인 된 클래스 뒤에있는 동기가 무엇인지 듣고 싶습니다. 클래스 봉인의 이점은 무엇입니까? 상속을 허용하지 않는 것이 얼마나 유용한 지, 그리고 이러한 클래스와 싸우는 유일한 사람이 아닐 가능성이 큽니다.
그렇다면 프레임 워크가 이러한 방식으로 설계된 이유는 무엇이며 모든 것을 개봉하는 데있어 확연한 변화가 아닐까요? 또 다른 이유가 있겠지만 그저 악한 것입니까?
답변:
이 항목에 대한 MSDN 문서는 클래스 봉인으로 확장 성 제한 입니다.
클래스는 상속을 위해 설계되거나 금지되어야합니다. 상속을 위해 디자인하는 데는 비용이 듭니다.
Effective Java의 항목 17은 이에 대해 자세히 설명합니다. Java의 컨텍스트로 작성되었다는 사실에 관계없이 조언은 .NET에도 적용됩니다.
개인적으로 클래스가 .NET에서 기본적으로 봉인되기를 바랍니다.
봉인에 대한 공식적인 Microsoft 지침은 이 질문이 약 9 년 전에 질문 된 이후로 발전한 것으로 보이며 , 그들은 옵트 인 철학 (기본적으로 봉인)에서 옵트 아웃 (기본적으로 봉인하지 않음)으로 이동했습니다.
X 정당한 이유없이 수업을 봉인 하지 마십시오 .
확장 성 시나리오를 생각할 수 없기 때문에 클래스를 봉인하는 것은 좋은 이유가 아닙니다. 프레임 워크 사용자는 편의 멤버를 추가하는 것과 같이 명확하지 않은 다양한 이유로 클래스에서 상속하는 것을 좋아합니다. 사용자가 유형에서 상속하려는 분명하지 않은 이유의 예는 봉인되지 않은 클래스를 참조하세요.
클래스를 봉인하는 이유는 다음과 같습니다.
- 클래스는 정적 클래스입니다. 정적 클래스 디자인을 참조하십시오.
- 클래스는 상속 된 보호 멤버에 보안에 민감한 비밀을 저장합니다.
- 클래스는 많은 가상 멤버를 상속하며 개별적으로 봉인하는 비용은 봉인되지 않은 상태로 두는 이점보다 더 큽니다.
- 이 클래스는 매우 빠른 런타임 조회가 필요한 속성입니다. 봉인 된 속성은 봉인되지 않은 속성보다 약간 더 높은 성능 수준을 갖습니다. 속성을 참조하십시오.
X 봉인 된 유형에 보호 또는 가상 멤버를 선언 하지 마십시오 .
정의에 따라 봉인 된 유형은 상속 될 수 없습니다. 이는 봉인 된 형식의 보호 된 멤버를 호출 할 수 없으며 봉인 된 형식의 가상 메서드를 재정의 할 수 없음을 의미합니다.
✓ 재정의하는 멤버를 봉인하는 것을 고려하십시오 . 가상 구성원 도입으로 인해 발생할 수있는 문제 (가상 구성원에서 논의 됨)는 재정의에도 적용되지만 정도는 약간 낮습니다. 재정의를 봉인하면 상속 계층 구조의 해당 지점에서 시작하는 이러한 문제로부터 보호됩니다.
실제로 ASP.Net Core 코드베이스 를 검색하면 약 30 개만 찾을 수 sealed class있으며 대부분은 속성 및 테스트 클래스입니다.
불변성 보존은 봉인에 찬성하는 좋은 주장이라고 생각합니다.
성능은 중요한 요소입니다. 예를 들어 Java의 문자열 클래스는 final (<-봉인 됨)이고 그 이유는 성능 때문입니다. 또 다른 중요한 점은 http://blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-brittle-base-classes 에 자세히 설명 된 취약한 기본 클래스 문제를 피하는 것 입니다. aspx
프레임 워크를 제공하는 경우 유지 보수 가능성 레거시 프로젝트에 중요하며 취약한 기본 클래스 문제를 방지하기 위해 프레임 워크를 업그레이드하는 것이 중요합니다.
씰링을 사용하면 약간의 성능 향상을 실현할 수 있습니다. 이것은 C ++의 세계에서보다 JIT 및 게으른 비관의 세계에서는 사실이 아니지만 .NET은 Java 컴파일러가 대부분 다른 디자인 철학으로 인해 비관적 인 것처럼 좋지 않기 때문에 여전히 유용합니다. vtable을 통해 간접적으로 호출하는 대신 가상 메서드를 직접 호출 할 수 있음을 컴파일러에 알립니다.
평등 비교와 같은 것을 위해 '폐쇄 된 세계'를 원할 때도 중요합니다. 일반적으로 가상 방법을 정의하면 실제로 아이디어를 구현하는 동등성 비교 개념을 정의하는 데 거의 몰두합니다. 반면에 가상 메서드를 사용하여 클래스의 특정 하위 클래스에 대해 정의 할 수 있습니다. 그 클래스를 봉인하면 평등이 실제로 유지됩니다.
클래스, 메서드 또는 속성을 봉인할지 여부를 결정하려면 일반적으로 다음 두 가지 사항을 고려해야합니다.
• 클래스를 사용자 지정하는 기능을 통해 파생 클래스가 얻을 수있는 잠재적 인 이점.
• 파생 클래스가 더 이상 올바르게 작동하지 않거나 예상대로 작동하지 않는 방식으로 클래스를 수정할 수있는 가능성.
추가 고려 사항은 봉인 된 클래스가 단위 테스트에서 스텁 될 수 없다는 것입니다. 에서 마이크로 소프트의 문서 :
스텁 유형은 가상 메소드 디스패치에 의존하기 때문에 봉인 된 클래스 또는 정적 메소드는 스텁 할 수 없습니다. 이러한 경우 shim 사용에 설명 된대로 shim 형식을 사용하여 단위 테스트를 위해 다른 어셈블리에서 응용 프로그램을 격리합니다.