Creo que en el centro de su pregunta se encuentra un malentendido sobre los tipos de referencia y valor. Esto es algo con lo que probablemente lucharon todos los desarrolladores de .NET y Java.
Una matriz es solo una lista de valores. Si se trata de una matriz de un tipo de referencia (por ejemplo, a string[]
), la matriz es una lista de referencias a varios string
objetos en el montón, ya que una referencia es el valor de un tipo de referencia. Internamente, estas referencias se implementan como punteros a una dirección en la memoria. Si desea visualizar esto, una matriz de este tipo se vería así en la memoria (en el montón):
[ 00000000, 00000000, 00000000, F8AB56AA ]
Esta es una matriz de string
que contiene 4 referencias a string
objetos en el montón (los números aquí son hexadecimales). Actualmente, solo el último string
realmente apunta a algo (la memoria se inicializa a todos los ceros cuando se asigna), esta matriz básicamente sería el resultado de este código en C #:
string[] strings = new string[4];
strings[3] = "something"; // the string was allocated at 0xF8AB56AA by the CLR
La matriz anterior estaría en un programa de 32 bits. En un programa de 64 bits, las referencias serían dos veces más grandes ( F8AB56AA
serían 00000000F8AB56AA
).
Si tiene una matriz de tipos de valores (digamos an int[]
), la matriz es una lista de enteros, ya que el valor de un tipo de valor es el valor en sí mismo (de ahí el nombre). La visualización de tal matriz sería esta:
[ 00000000, 45FF32BB, 00000000, 00000000 ]
Esta es una matriz de 4 enteros, donde solo al segundo int se le asigna un valor (a 1174352571, que es la representación decimal de ese número hexadecimal) y el resto de los enteros sería 0 (como dije, la memoria se inicializa a cero y 00000000 en hexadecimal es 0 en decimal). El código que produjo esta matriz sería:
int[] integers = new int[4];
integers[1] = 1174352571; // integers[1] = 0x45FF32BB would be valid too
Esta int[]
matriz también se almacenaría en el montón.
Como otro ejemplo, la memoria de una short[4]
matriz se vería así:
[ 0000, 0000, 0000, 0000 ]
Como el valor de a short
es un número de 2 bytes.
Cuando se almacena un tipo de valor, es solo un detalle de implementación, como Eric Lippert explica muy bien aquí , no es inherente a las diferencias entre los tipos de valor y referencia (que es la diferencia en el comportamiento).
Cuando pasa algo a un método (ya sea un tipo de referencia o un tipo de valor), una copia del valor del tipo se pasa realmente al método. En el caso de un tipo de referencia, el valor es una referencia (piense en esto como un puntero a una pieza de memoria, aunque eso también es un detalle de implementación) y en el caso de un tipo de valor, el valor es la cosa misma.
// Calling this method creates a copy of the *reference* to the string
// and a copy of the int itself, so copies of the *values*
void SomeMethod(string s, int i){}
El boxeo solo ocurre si convierte un tipo de valor en un tipo de referencia. Este código recuadros:
object o = 5;