.NET 프레임 워크에 왜 클래스의 개념이 일류 유형이 없는가? 객체 인스턴스의 실제 유형에 따라

C #과 .NET 프레임 워크는 델파이의 주요 개발자 인 앤더스 헤 즐스 버그 (Anders Hejlsberg)가 설계 한 본질적으로 “델파이가 자바처럼 느껴지도록 다시 작성했다”는 역사에 익숙한 사람들에게 잘 알려져 있습니다. 그 이후로 상황이 상당히 다양해졌지만, 유사점 초기에는 .NET이 실제로 볼랜드의 제품이라는 진지한 추측이있었습니다.

그러나 최근 몇 가지 .NET 관련 자료를 살펴 보았으며 Delphi의 가장 흥미롭고 유용한 기능 중 하나는 클래스 데이터 개념이라는 개념이 완전히 누락 된 것 같습니다. 익숙하지 않은 사람들에게 유형은 .NET TClassType유형 과 유사한 클래스에 대한 참조를 나타냅니다 . 그러나 .NET Type이 리플렉션에 사용 하는 경우 Delphi는 TClass언어의 매우 중요한 내장 부분으로 사용합니다. 클래스 하위 유형 변수 및 가상 클래스 메서드와 같이 존재하지 않고 존재할 수없는 다양한 유용한 관용구를 허용합니다.

모든 OO 언어에는 가상 클래스가 있으며 다른 클래스는 다른 방법으로 동일한 기본 개념의 메소드를 구현 한 다음 호출되는 객체 인스턴스의 실제 유형에 따라 런타임에 올바른 메소드를 호출합니다. 델파이는이 개념을 클래스로 확장합니다. TClass 참조가 특정 클래스 하위 유형으로 정의 된 경우 (즉 class of TMyClass, 변수 TMyClass가 클래스 범위 가상 메소드가 첨부 된 (계층 외부에서는 상속 되지 않는 클래스 참조를 허용 할 수 있음을 의미 )) 실제 유형의 클래스를 사용하여 인스턴스없이 호출 할 수 있습니다. 예를 들어,이 패턴을 생성자에 적용하면 팩토리 구현이 간단합니다.

.NET에는 동등한 것으로 보이지 않습니다. 클래스 참조 (특히 가상 생성자 및 기타 가상 클래스 메서드)만큼 유용한 것처럼, 왜 그들이 빠진 이유에 대해 말한 적이 있습니까?

구체적인 예

양식 역 직렬화

Delphi VCL은 DFM컴포넌트 계층을 설명하기위한 DSL 형식의 양식을 저장합니다 . 양식 판독기는 DFM 데이터를 구문 분석 할 때 다음과 같이 설명 된 오브젝트에서 실행됩니다.

object Name: ClassName
   property = value
   property = value
   ...
   object SubObjectName: ClassName
      ...
   end
end

여기서 흥미로운 것은 ClassName부분입니다. 각 구성 요소 클래스 TClassinitialization시간에 구성 요소 스트리밍 시스템에 등록합니다 (정적 생성자는 약간 다르지만 시작시 즉시 발생한다고 생각합니다). 클래스 이름을 키로 사용하여 문자열-> TClass 해시 맵에 각 클래스를 등록합니다.

각 구성 요소는 TComponent에서 유래하며 단일 인수를 취하는 가상 생성자가 Owner: TComponent있습니다. 모든 구성 요소는이 생성자를 재정 의하여 자체 초기화를 제공 할 수 있습니다. DFM 리더는 클래스 이름을 읽을 때 위에서 언급 한 해시 맵에서 이름을 찾아 해당 클래스 참조를 검색하거나 (없는 경우 예외 발생) 가상 TComponent 생성자를 호출합니다. 등록 함수는 TComponent에서 내려 오는 데 필요한 클래스 참조를 사용하기 때문에 적절한 유형의 객체로 끝납니다.

이 기능이 부족하기 때문에 WinForms와 동등한 기능은 … 음 .. .NET 언어를 완전히 다시 구현하려면 새로운 .NET 언어가 필요합니다. 생각할 때 약간 충격적입니다. CLR의 핵심은 여러 언어가 동일한 기본 인프라를 사용하도록하는 것이므로 DFM 스타일 시스템은 완벽하게 이해 될 것입니다.

확장 성

내가 작성한 이미지 관리자 클래스 에는 데이터 소스 (예 : 이미지 파일의 경로)가 제공되고 컬렉션에 없지만 데이터 소스에서 사용 가능한 이름을 검색하려고하면 새 이미지 객체를 자동으로로드 할 수 있습니다. class of생성 할 새 객체의 클래스를 나타내는 기본 이미지 클래스 로 입력 된 클래스 변수 가 있습니다. 기본적으로 제공되지만 특별한 목적으로 새 이미지를 만들 때 이미지를 다른 방식으로 설정해야한다는 몇 가지 사항이 있습니다. (알파 채널없이 생성하고 PNG 파일에서 특수 메타 데이터를 검색하여 스프라이트 크기 등을 지정하는 등)

이것은 많은 양의 구성 코드를 작성하고 새로운 객체를 만들 수있는 모든 메소드에 특수 옵션을 전달하여 수행 할 수 있습니다 … 또는 가상 메소드를 재정의하는 기본 이미지 클래스의 서브 클래스를 만들 수 있습니다 해당 측면이 구성된 다음 try / finally 블록을 사용하여 필요에 따라 “기본 클래스”특성을 임시로 대체 한 후 복원하십시오. 클래스 참조 변수로 수행하는 것이 훨씬 간단하며 대신 제네릭으로 수행 할 수있는 것이 아닙니다.



답변

.NET (CLR)은 초기에는 “COM + 런타임”이라고하는 Microsoft의 COM (Component Object Model)의 3 세대였습니다. Microsoft Visual Basic 및 COM / ActiveX 컨트롤 시장은 Borland Delphi보다 특정 CLR 아키텍처 호환성 선택에 훨씬 더 많은 영향을 미쳤습니다. (델파이가 ActiveX 컨트롤을 채택했다는 것은 확실히 ActiveX 생태계를 성장시키는 데 도움이되었지만 COM / ActiveX는 델파이 이전에 존재했습니다)

COM의 아키텍처는 C (C ++ 아님)에서 개발되었으며 클래스가 아닌 인터페이스에 중점을 두었습니다. 또한 지원되는 객체 구성으로, COM 객체는 여러 개의 서로 다른 객체로 구성 될 수 있으며 IUnknown 인터페이스가 서로 연결되어 있습니다. 그러나 IUnknown은 가능한 한 언어 독립적으로 디자인 된 COM 개체 생성에 아무런 역할을하지 않았습니다. 객체 생성은 일반적으로 IClassFactory에 의해 처리되고 ITypeLibrary 및 관련 인터페이스에 의해 반영됩니다. 이러한 분리 문제는 구현 언어와 무관했으며 각 핵심 COM 인터페이스의 기능은 최소 및 직교로 유지되었습니다.

따라서 COM 및 ActiveX 컨트롤의 인기로 인해 COM IUnknown, IClassFactory 및 ITypeLibrary를 지원하도록 .NET 아키텍처가 구축되었습니다. COM에서 이러한 인터페이스는 반드시 동일한 객체에있을 필요는 없었으므로 이러한 인터페이스가 모두 합쳐지지는 않았습니다.