Я вважаю, що найкориснішим є уявлення про типи посилань як про ідентифікатори об’єктів. Якщо у когось є змінна типу класу Car
, оператор myCar = new Car();
просить систему створити нову машину та повідомити її ідентифікатор (припустимо, це об’єкт №57); потім він поміщає "об'єкт №57" у змінну myCar
. Якщо хтось пише Car2 = myCar;
, це записує "об'єкт №57" у змінну Car2. Якщо хтось пишеcar2.Color = blue;
, це вказує системі знайти автомобіль, ідентифікований Car2 (наприклад, об’єкт №57), і пофарбувати його в синій колір.
Єдиними операціями, які виконуються безпосередньо над ідентифікаторами об'єкта, є створення нового об'єкта та отримання ідентифікатора, отримання "порожнього" ідентифікатора (тобто нульовий), копіювання ідентифікатора об'єкта в змінну або місце зберігання, яке може його утримувати, перевірка, чи є два ідентифікатори об'єктів збігаються (посилаються на той самий об'єкт). Усі інші запити вимагають від системи знайти об’єкт, на який посилається ідентифікатор, та діяти на нього (не впливаючи на змінну чи іншу сутність, що тримала ідентифікатор).
У існуючих реалізаціях .NET змінні об'єкти, швидше за все, містять вказівники на об'єкти, що зберігаються у купі, що збирається сміттям, але це не корисна деталь реалізації, оскільки існує критична різниця між посиланням на об'єкт та будь-яким іншим покажчиком. Як правило, вважається, що вказівник відображає місце розташування чогось, що залишатиметься досить довгим, щоб працювати з ним. Посилання на об'єкти ні. Шматок коду може завантажити регістр SI з посиланням на об'єкт, розташований за адресою 0x12345678, почати його використовувати, а потім перервати, поки збирач сміття переміщує об'єкт на адресу 0x23456789. Це би звучало як катастрофа, але сміття вивчить метадані, пов’язані з кодом, зауважимо, що код використовував SI для утримання адреси об’єкта, який він використовував (тобто 0x12345678), визначити, що об’єкт, що знаходився в 0x12345678, було переміщено в 0x23456789, та оновити SI, щоб він містив 0x23456789, перш ніж він повернувся. Зверніть увагу, що в цьому сценарії чисельне значення, що зберігається у SI, було змінено збирачем сміття, але воно посилалосяодин і той же об'єкт до переїзду та після. Якщо перед переміщенням воно посилалося на 23592-й об'єкт, створений з моменту запуску програми, він буде продовжувати робити це після цього. Цікаво, що .NET не зберігає жодного унікального та незмінного ідентифікатора для більшості об’єктів; з урахуванням двох знімків пам'яті програми, не завжди можна буде визначити, чи існує якийсь конкретний об'єкт у першому знімку, або якщо всі сліди до нього були залишені та створено новий об'єкт, який, схоже, схожий на всі спостережувані деталі.