모든 독립형 힙 객체는 Object
; 모든 독립형 힙 객체에는 유형을 식별하는 수단과 같은 특정 공통 측면이 있어야하기 때문에 의미가 있습니다. 그렇지 않으면 가비지 수집기에서 알 수없는 형식의 힙 객체에 대한 참조가 있으면 해당 객체와 관련된 메모리 Blob 내에서 어떤 비트가 다른 힙 객체에 대한 참조로 간주되는지 알 수있는 방법이 없습니다.
또한, 타입 시스템 내에서, 구조의 멤버와 클래스의 멤버를 정의하기 위해 동일한 메커니즘을 사용하는 것이 편리합니다. 값 유형 저장 위치 (변수, 매개 변수, 필드, 배열 슬롯 등)의 동작은 클래스 유형 저장 위치의 동작과 매우 다르지만 이러한 동작 차이는 소스 코드 컴파일러 및 실행 엔진 ( 타입 시스템으로 표현되는 것이 아니라 JIT 컴파일러).
그 결과 값 유형을 정의하면 스토리지 위치 유형과 힙 객체 유형의 두 가지 유형이 효과적으로 정의됩니다. 전자는 암시 적으로 후자로 변환 될 수 있고, 후자는 타입 캐스트를 통해 전자로 변환 될 수있다. 두 유형의 변환 모두 문제의 유형의 한 인스턴스에서 다른 필드로 모든 공용 및 개인 필드를 복사하여 작동합니다. 또한 일반 제약 조건을 사용하여 복사본을 먼저 만들지 않고도 값 형식 저장소 위치에서 직접 인터페이스 멤버를 호출 할 수 있습니다.
값 유형 힙 객체에 대한 참조는 값 유형이 아닌 클래스 참조처럼 동작하기 때문에이 모든 것이 중요합니다. 예를 들어 다음 코드를 고려하십시오.
string testEnumerator <T> (T it) 여기서 T : IEnumerator <string>
{
var it2 = 그것;
it.MoveNext ();
it2.MoveNext ();
그것을 돌려줍니다.
}
공공 무효 시험 ()
{
var theList = new List <문자열> ();
theList.Add ( "Fred");
theList.Add ( "George");
theList.Add ( "Percy");
theList.Add ( "Molly");
theList.Add ( "Ron");
var enum1 = theList.GetEnumerator ();
IEnumerator <문자열> enum2 = enum1;
Debug.Print (testEnumerator (enum1));
Debug.Print (testEnumerator (enum1));
Debug.Print (testEnumerator (enum2));
Debug.Print (testEnumerator (enum2));
}
testEnumerator()
메소드에 값 유형의 저장 위치가 전달 되면 전달 된 값에서 it
퍼블릭 및 프라이빗 필드가 복사 된 인스턴스가 수신됩니다. 로컬 변수 it2
는 필드가 모두에서 복사 된 다른 인스턴스를 보유 it
합니다. 부름MoveNext
에하는 것은 it2
영향을주지 않습니다 it
.
위 코드에 클래스 유형의 저장 위치가 전달되면 전달 된 값은 it
, 그리고 it2
, 모두 같은 객체를 참조하고, 따라서 호출 MoveNext()
그 중 효과적으로 그들 모두에 그것을 호출에.
효과적으로 캐스팅 하면 값 유형에서 클래스 유형 List<String>.Enumerator
으로 IEnumerator<String>
효과적으로 전환됩니다. 힙 객체의 유형은 동일 List<String>.Enumerator
하지만 동작이 동일한 이름의 값 유형과는 매우 다릅니다.
object
이 같은 모든 객체에서 몇 가지 기본적인 기능을 제공하기 때문에 일부에서 .NET 프레임 워크ToString()
와GetHashCode()