Где находится ссылка на объект и что происходит, когда вы передаете ссылку на объект по ссылке? - PullRequest
1 голос
/ 29 февраля 2012

В контексте C #:

Давайте предположим следующий код ...

public class Foo
    {
        MrObject object1;
        MrObject object2;
        MrObject object3;
        MrObject object4;

        MrStruct struct1;
        MrStruct struct2;
        MrStruct struct3;
        MrStruct struct4;

        int i;

        public Foo()
        {
            object1 = new MrObject(1);  /// Alpha
            object2 = new MrObject(2);  /// Bravo
            object3 = new MrObject(3);  /// Charlie
            object4 = new MrObject(4);  /// Delta

            i = 1;

            InitializeComponent(); // POINT A
            ByValByRef(object1, ref object2);

        }


        public void ByValByRef(MrObject o1, ref MrObject o2)
        {
            o1.foo = 5; // POINT B
            o1 = object3; // POINT C
            o2.foo = 6; // POINT D
            o2 = object4; // POINT E
            return;
        }

Насколько я понимаю, в точке // POINT A - вы создали четыре экземпляра MyObject.Эти четыре экземпляра живут в куче.- у вас есть четыре ссылки на эти случаи. ВОПРОС 1: Где они живут?

Насколько я понимаю, в // POINT B - вы создали новую ссылку на 'Alpha' с именем 'o1'.Эта ссылка добавляется и находится в стеке.Когда метод возвращается, эта ссылка удаляется.
- у вас есть ссылка с именем 'o2'. ВОПРОС 2: Является ли это новой ссылкой, которая добавляется и хранится в стеке и ссылается на ссылку 'object2'?Или 'o2' просто псевдоним, поддерживаемый в коде (а не в памяти), и на самом деле в памяти остается только одна ссылка на 'Bravo', называемая 'object2', и когда этот код фактически выполняется, обрабатывается 'o2.foo'как 'object2.foo'?

1 Ответ

1 голос
/ 29 февраля 2012

Насколько я понимаю, на // POINT A - вы создали четыре экземпляры MyObject. Эти четыре экземпляра живут в куче.

правый. Для каждого объекта выделена память в куче.

у вас есть четыре ссылки на эти экземпляры. ВОПРОС 1: Где они жить?

Когда вы создавали объекты, вы присваивали (ссылку) каждому из них на отдельное поле объекта Foo. Эти поля «живут» в памяти, выделенной для объекта Foo, который также почти наверняка находится где-то в куче.

Насколько я понимаю, на // POINT B - вы создали новый ссылка на «Альфа» с именем «o1». Эта ссылка добавлена ​​и живет в стеке. Когда метод возвращается, эта ссылка удаляется.

Да, в POINT B параметр o1 также хранит ссылку на MrObject, который был передан в качестве аргумента. o1 живет в краткосрочном магазине, который, как правило, будет «стеком». Когда метод завершится, пространство в кратковременном хранилище, используемом для o1, станет доступным для другого использования, и сборщик мусора больше не будет рассматривать o1 как известный живой корень.

у вас есть ссылка с именем 'o2'. ВОПРОС 2: Это новая ссылка который добавляется и находится в стеке и ссылается на объект2 ссылка? Или 'o2' просто псевдоним, поддерживаемый в коде (а не в памяти) и на самом деле в памяти есть только одна ссылка на «Браво» называется «объект2» и когда этот код на самом деле выполняется, «o2.foo» рассматривается как «object2.foo»?

А теперь мы переходим к сложной части вашего вопроса. o2 является ссылкой другого рода. Это не ссылка на объект в куче, а скорее псевдоним (как вы предполагаете) к полю object2 объекта Foo. o2 все еще занимает место в краткосрочном хранилище, так как это все еще аргумент метода.

Кстати, тот факт, что в памяти есть "только одна ссылка на Bravo", - это не то, о чем вам следует беспокоиться. Ссылки, которые достижимы от известных корней GC , определяют, можно ли безопасно собрать конкретный объект.

...