참조 유형을 개체 ID를 보유하는 것으로 생각하는 것이 가장 도움이됩니다. 클래스 유형의 변수가있는 경우 Car명령문 myCar = new Car();은 시스템에 새 자동차를 만들고 ID를보고하도록 요청합니다 (객체 # 57이라고 가정 해 보겠습니다). 그런 다음 "object # 57"을 변수에 넣습니다 myCar. 만약 하나 개 쓰기 Car2 = myCar;변수 Car2에 "개체 # 57"를 쓴다. 라고 쓰면 car2.Color = blue;시스템이 Car2 (예 : 객체 # 57)로 식별되는 자동차를 찾고 파란색으로 칠하도록 지시합니다.
객체 ID에서 직접 수행되는 유일한 작업은 새 객체 생성 및 ID 가져 오기, "빈"ID (예 : null) 가져 오기, 객체 ID를 저장할 수있는 변수 또는 저장 위치에 복사, 두 가지 여부 확인입니다. 개체 ID가 일치합니다 (동일한 개체 참조). 다른 모든 요청은 시스템에 ID가 참조하는 객체를 찾고 해당 객체에 대해 조치를 취하도록 요청합니다 (ID를 보유한 변수 또는 기타 엔티티에 영향을주지 않음).
.NET의 기존 구현에서 개체 변수는 가비지 수집 된 힙에 저장된 개체에 대한 포인터를 보유 할 가능성이 있지만 개체 참조와 다른 종류의 포인터간에 중요한 차이가 있기 때문에 구현 세부 사항은 도움이되지 않습니다. 포인터는 일반적으로 작업 할 수있을만큼 오래 머무를 위치를 나타내는 것으로 간주됩니다. 개체 참조는 그렇지 않습니다. 코드 조각은 주소 0x12345678에있는 개체에 대한 참조와 함께 SI 레지스터를로드하고 사용을 시작한 다음 가비지 수집기가 개체를 주소 0x23456789로 이동하는 동안 중단 될 수 있습니다. 그것은 재앙처럼 들리 겠지만, 쓰레기는 코드와 관련된 메타 데이터를 조사 할 것이고, 코드가 SI를 사용하여 그것이 사용하고 있던 객체의 주소를 보유하고 있다는 것을 관찰 할 것입니다 (예 : 0x12345678). 0x12345678에 있던 개체가 0x23456789로 이동되었는지 확인하고 SI를 업데이트하여 반환되기 전에 0x23456789를 유지합니다. 이 시나리오에서 SI에 저장된 숫자 값은 가비지 수집기에 의해 변경되었지만이동 전과 후에 동일한 개체 . 이동하기 전에 프로그램 시작 이후 생성 된 23,592 번째 개체를 참조하는 경우 나중에 계속 그렇게합니다. 흥미롭게도 .NET은 대부분의 개체에 대해 고유하고 변경할 수없는 식별자를 저장하지 않습니다. 프로그램 메모리의 두 스냅 샷이 주어지면 첫 번째 스냅 샷의 특정 개체가 두 번째 스냅 샷에 존재하는지 또는 모든 추적이 취소되고 새 개체가 생성되었는지 여부를 항상 알 수있는 것은 아닙니다. 모든 관찰 가능한 세부 사항.