2009-04-18 20 views
27

Otra pregunta reciente de la entrevista de C# que tuve fue si sabía lo que es Boxeo y Unboxing. Le expliqué que los tipos de valores están en pila y los tipos de referencia en Heap. Cuando un valor se convierte en un tipo de referencia, lo llamamos boxeo y viceversa.Boxeo vs Unboxing

Entonces me preguntó para calcular esto:

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

¿Cuál es i?

metí la pata y dijo 50, donde su realidad 20. Ahora creo entenderlo por qué, sin embargo, cuando estaba jugando con diferentes combinaciones Me sorprendió ver esto:

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

que estaba esperando a ver b == 2 también, pero no lo es, ¿por qué? ¿Es porque el segundo boxeo destruye y reemplaza todo el objeto a en el montón?

Porque si hago esto, está bien:

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; 

¿Cuál es t2.x? Debería ser 3, y lo es. Pero este no es un ejemplo de boxeo/unboxing en absoluto, ¿es correcto? Entonces, ¿cómo resumirías esto?

¿Podrían los valores llegar a ser iguales en una conversión de boxeo/unboxing como la anterior?

+1

también ver http://stackoverflow.com/questions/13055/what-is-boxing-and-unboxing-and-what-are-the -trade-offs para una lectura general – nawfal

Respuesta

5
  1. Tienes razón, la segunda asignación reemplaza a la primera. No cambia el valor en caja.

  2. Su ejemplo no hace uso del boxeo. El valor (int) se almacena como un int y no en un recuadro.

  3. No, el boxeo aún conserva la garantía de inmutabilidad.

+0

Hola, gracias por tu respuesta. ¿Podrías por favor elaborar un poco más sobre "el boxeo todavía conserva la garantía de inmutabilidad"? Gracias kave – Houman

+1

La mayoría de los tipos de valores son inmutables, por ejemplo: Un int solo puede tener un valor. Si cambia el valor, básicamente está creando una nueva int. .NET mantiene esta inmutabilidad para los objetos encuadrados: si le asigna un nuevo valor, está creando un nuevo int encuadrado. Lo mismo se aplica a las estructuras en caja. – grover

+0

Tiene perfecto sentido. Gracias – Houman

2

Yo estaba esperando a ver b == 2, así, pero no lo es, ¿por qué? ¿es porque el segundo boxeo destruye y reemplaza por el todo (a) -objeto en el montón?

No, no exactamente. Deja el objeto tal como está en el montón (como la variable b también hace referencia a él) y crea un nuevo objeto para el nuevo valor al que hará referencia la variable a.

Tiene razón en que su segundo ejemplo no utiliza el boxeo. No puede acceder a un valor que está encuadrado de ninguna otra manera que no sea unboxing, por lo que no hay forma de cambiar un valor encuadrado.

Ni siquiera una estructura mutable como Point se puede cambiar cuando se encuadra. Para acceder a las propiedades de la estructura, debe desempaquetarla, de modo que no pueda modificar la estructura en caja.

1

b sigue siendo 1 porque b es una referencia que aún apunta al objeto en el montón con un valor de 1. a es 2 porque lo asignó a un nuevo objeto en el montón con un valor de 2.

t2.x es 3 porque t y t2 son dos referencias diferentes al mismo objeto en el montón.

0

Creo que la respuesta a su pregunta con unboxing es que: El resultado de una conversión de unboxing es una variable temporal (más detalles: link).

creo que estaba tratando de hacer algo 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 

El código anterior no compilará - detalles en el enlace de arriba, y creo que esta es la respuesta a su pregunta:

Esperaba ver b == 2 también, pero no lo es, ¿por qué? ¿es porque el segundo boxeo destruye y reemplaza por el todo (a) -objeto en el montón?

+0

Vale la pena señalar que en C++/CLI, no hay dificultad para modificar los objetos del montón encajonados directamente dentro del código confiable y verificable. – supercat

8

muy corta: el boxeo significa la creación de una nueva instancia de un tipo de referencia. Si sabes esto, entiendes que una instancia no cambia al crear otra.

Lo que está haciendo con a = 2 no está cambiando el valor en la 'caja', está creando una nueva instancia de un tipo de referencia. Entonces, ¿por qué debería cambiar algo más?

+1

buena explicación, ¿ahora qué sucede cuando unbox? Cómo se destruye la nueva instancia del tipo de referencia? – SoftwareGeek

+1

Los tipos de referencia siempre son destruidos por la recolección de basura. Entonces será destruido cuando ya no se haga referencia a él. –

+0

corto n dulce respuesta, muy agradable – FosterZ

2

Aquí es otra variante interesante que apoya los comentarios 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 
Cuestiones relacionadas