Вопрос

Еще один недавний вопрос в интервью C #, который у меня возник, касался того, знаю ли я, что такое упаковка и распаковка.Я объяснил, что типы значений находятся в стеке, а ссылочные типы - в куче.Когда значение преобразуется к ссылочному типу, мы называем это упаковкой, и наоборот.

Затем он попросил меня рассчитать это:

int i = 20;
object j = i;
j = 50;

Что такое i?

Я все перепутал и сказал 50, хотя на самом деле это 20.Теперь я, кажется, понимаю, почему, однако, когда я играл с разными комбинациями, я был удивлен, увидев это:

Object a = 1; // Boxing
Object b = a; // referencing the pointer on stack to both objects on heap
a = 2; // Boxing

Я ожидал увидеть b == 2 также, но это не так, почему?Это потому, что второй бокс разрушает и заменяет весь a объект в куче?

Потому что, если я сделаю это, все будет в порядке:

public class TT
{
    public int x;
}

TT t = new TT();
t.x = 1;
TT t2 = new TT();
t2.x = 2;
t = t2;
t.x = 3;

Что такое t2.x?Должно быть 3, и это так.Но это вообще не пример упаковки / распаковки, правильно ли это?Итак, как бы вы подытожили это?

Могут ли значения когда-либо стать одинаковыми при преобразовании упаковки / распаковки, как указано выше?

Это было полезно?

Решение

  1. Вы правы, второе задание заменяет первое.Это не изменяет значение в штучной упаковке.

  2. В вашем примере не используется бокс.Значение (int) сохраняется как int и не помещается в коробку.

  3. Нет, бокс по-прежнему сохраняет гарантию неизменности.

Другие советы

Очень короткий:бокс означает создание нового экземпляра ссылочного типа.Если вы знаете это, вы понимаете, что один экземпляр не изменяется при создании другого.

Что вы делаете с a = 2 не изменяя значение в "поле", вы создаете новый экземпляр ссылочного типа.Так почему же что-то еще должно измениться?

Я также ожидал увидеть b == 2, но это не так, почему?это потому, что второй блок уничтожает и заменяет весь (a)-объект в куче?

Нет, не совсем.Он оставляет объект таким, какой он есть в куче (как b переменная также ссылается на нее) и создает новый объект для нового значения, которое a переменная будет ссылаться.

Вы правы в том, что во втором примере не используется boxing .Вы не можете получить доступ к значению, которое помещено в коробку, каким-либо другим способом, кроме как распаковав его, поэтому нет способа изменить значение в коробке.

Даже такой изменяемой структуры, как Point может быть изменен при упаковке в коробку.Чтобы получить доступ к свойствам структуры, вы должны распаковать ее, поэтому вы не можете изменить структуру в штучной упаковке на месте.

Вот еще один интересный вариант, который подтверждает комментарии Стефана:

        int i = 2;
        object a = i; // Boxing
        object b = a; // Referencing same address on heap as 'a', b == a

        b = i; // New boxing on heap with reference new address, b != a

b по-прежнему равно 1, потому что b - это ссылка, которая по-прежнему указывает на объект в куче со значением 1.a равно 2, потому что вы присвоили его новому объекту в куче со значением 2.

t2.x равно 3, потому что t и t2 - это две разные ссылки на один и тот же объект в куче.

Я думаю, что ответ на ваш вопрос с распаковкой заключается в том, что:Результатом преобразования при распаковке является временная переменная (подробнее: Ссылка).

Я думаю, ты пытался сделать что-то вроде:

object a = new Point(10,10);
object b = new Point(20,20);
a = b;

((Point) b).X = 30; //after this operation also a.X should be 30

Приведенный выше код не будет компилироваться - подробности по ссылке выше, и я думаю, что это ответ на ваш вопрос:

Я также ожидал увидеть b == 2, но это не так, почему?это потому, что второй блок уничтожает и заменяет весь (a)-объект в куче?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top