원칙적으로:
1. C++ 템플릿과 마찬가지로 C# 제네릭의 핵심은 유형 유형입니다.
유형을 정의하고 인스턴스화된 각 객체는 특정 유형이므로 유형 유형이라고 합니다.
2. 인스턴스화되면 두 가지 상황으로 구분됩니다.
참조 유형 및 값 유형
참조 유형은 본질적으로 메모리 주소인 포인터이므로 특정 비트 길이를 가진 시스템에서는 포인터 변수가 사용하는 바이트 수가 동일합니다. 예를 들어 32비트 시스템은 4바이트를 사용합니다.
제네릭의 본질은 정의된 유형의 유형이라는 것입니다. 컴파일 후에는 이 유형 정의의 특성을 설명하는 바이너리 코드가 메모리에 저장됩니다.
여기서는 먼저 소스 코드를 컴파일한 후 인스턴스화된 객체의 유형 정의 및 메모리 할당에 대해 설명합니다. 소스 코드가 컴파일된 후 실행 중에 프로그램 파일(예: exe 파일)을 프로그래밍하고 메모리 공간에 로드해야 합니다(최신 OS). 매핑을 사용하고, 논리적으로 메모리를 점유하고, 물리적으로 페이징 방법을 사용하고, 데이터의 해당 부분을 물리적 메모리로 전송하는 방법을 사용합니다.
클래스를 정의할 때 컴파일 후 클래스에 대한 설명(어떤 데이터 멤버, 어떤 멤버 함수, 각각의 권한 등에 대한 정보)이 exe 파일의 일부를 구성하고 실행 후 메모리에 로드됩니다. 이진 데이터는 메모리 주소에 0x0001로 설정됩니다.
클래스 개체를 인스턴스화하는 경우 C++에서는 클래스 인스턴스화 개체가 스택에 메모리를 할당하고, 클래스 인스턴스화 개체는 힙에 메모리를 할당합니다. (예: Windows 32비트 시스템에서는 프로그램 메모리 공간이 4G입니다.) exe로 매핑된 메모리 이외의 남은 메모리에서는 인스턴스화된 개체가 수명을 초과하거나 힙에서 해제되면 메모리 공간이 반환됩니다. 프로세스에.
마찬가지로 일반 인코딩된 이진 데이터는 exe 파일에 포함되어 메모리에 로드됩니다.
제네릭이 인스턴스화될 때, 즉 특정 유형이 컴파일될 때(C#에서 제네릭을 인스턴스화하는 프로세스는 컴파일 중에 수행됩니다. 즉, 코드에 사용되는 인스턴스화된 제네릭이 각 특정 유형에 대해 바이너리입니다. 코드는 컴파일 중에 생성되고 제네릭 자체의 바이너리 코드는 exe 파일에 기록됩니다. exe 파일에서 인스턴스화된 각 유형의 바이너리 코드는 얼마나 많은 공간을 차지해야 합니까?
C#에서는 참조 유형과 값 유형을 구별해야 합니다. 제네릭이 프로그램 소스 코드에서 두 가지 참조 유형과 두 가지 값 유형을 인스턴스화한다고 가정합니다.
그런 다음 참조 유형의 경우:
하나는 4바이트 포인터를 사용하고, 두 개는 두 개의 포인터를 사용합니다. 이진 데이터는 사용된 유형(예: 벡터<myClass>의 myClass)을 가리킵니다. myClass는 정의된 클래스 유형입니다. 컴파일 후 이진 데이터는 exe 파일에 저장됩니다. ) (상대 주소는 메모리에 로드된 후 메모리 주소로 변환됩니다.) 이는 참조 유형의 인스턴스화된 객체가 힙에 할당되어 런타임에 실행되기 때문입니다. 이 때 주소는 바이너리를 가져옵니다. myClass 유형으로 설명되는 데이터를 인스턴스화한 객체가 차지하는 메모리 공간을 계산하고 이를 힙에 할당합니다.
값 유형의 경우:
값 유형에는 구조 및 사전 정의된 데이터 유형이 포함됩니다. 이러한 유형(예: vector<int>, vector<double>)으로 제네릭을 인스턴스화하면 두 클래스의 실제 바이너리 데이터가 생성되어 인스턴스화할 때 이를 나타냅니다. (물론 참조처럼 런타임에 계산하고 인코딩할 수도 있습니다.) 하지만 값 유형이 스택에 할당되고 효율성을 얻기 위해 유연성이 손실되므로 실행합니다. 이와 같이)