Pergunta

Outra recente questão C # entrevista que eu tinha era se eu sabia o boxing e unboxing é. Expliquei-lhe que tipos de valores estão em Pilha e tipos de referência na Heap. Quando um valor é convertido para um tipo de referência, chamamos isso de boxe e vice-versa.

Então ele me pediu para calcular o seguinte:

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

O que é i?

Eu estraguei tudo e disse 50, onde a sua realmente 20. Agora eu acho que entendo por que, no entanto, quando eu estava jogando com diferentes combinações Fiquei surpreso ao ver o seguinte:

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

Eu estava esperando para ver b == 2 bem, mas não é, por quê? Será que é porque o segundo destrói boxe e substitui todo o objeto a na pilha?

Porque se eu fizer isso, tudo bem:

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;

O que é t2.x? Deve ser 3, e é. Mas este não é um exemplo de boxe / unboxing em tudo, isso é correto? Então, como você resumiria isso?

Poderiam os valores nunca se tornar o mesmo em um boxe / conversão unboxing como acima?

Foi útil?

Solução

  1. Você tem razão a segunda tarefa substitui o primeiro. Isso não muda o valor em caixa.

  2. O seu exemplo não fazer uso de boxe. O valor (int) é armazenado como um int e não em caixa.

  3. Não, o boxe ainda mantém a garantia de imutabilidade.

Outras dicas

Muito curto: meios de boxe criar uma nova instância de um tipo de referência . Se você sabe disso, você entende que uma instância não muda criando outro.

O que você está fazendo com a = 2 não está mudando o valor na 'caixa', você está criando uma nova instância de um tipo de referência. Então, por que qualquer outra coisa mudança?

Eu estava esperando para ver b == 2, bem como, mas não é, por quê? é porque o segundo destrói boxe e substitui o todo (a) -object no montão?

Não, não exatamente. Ele deixa o objeto como ele é na pilha (como a variável b também está fazendo referência a ele) e cria um novo objeto para o novo valor, que a variável a fará referência.

Você está certo de que seu segundo exemplo não usa o boxe. Você não pode acessar um valor que está encaixotado em qualquer outra forma que não unboxing-lo, por isso não há maneira de mudar um valor em caixa.

Nem mesmo um struct mutável como Point pode ser alterado quando encaixotado. Para acessar as propriedades da estrutura que você tem que unbox-lo, então você não pode mudar a estrutura em caixa no lugar.

Aqui está outra variação interessante que suporta comentários de Stefan:

        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 ainda é 1 porque b é uma referência que aponta ainda para o objeto na pilha com um valor de 1. a é 2, porque você atribuiu a um novo objeto na pilha com um valor de 2.

t2.x é 3 porque t e t2 são duas referências diferentes para o mesmo objeto na pilha.

Eu acho que a resposta à sua pergunta com unboxing é que: O resultado de uma conversão unboxing é uma variável temporária (mais detalhes: link ).

Eu acho que você estava tentando fazer sth como:

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

O código acima não irá compilar - detalhes no link acima, e eu acho que esta é a resposta à sua pergunta:

Eu estava esperando para ver b == 2, bem como, mas não é, por quê? é porque o segundo destrói boxe e substitui o todo (a) -object no montão?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top