7

Supongamos el siguiente código, sin ninguna palabra clave ref, que obviamente no reemplazará la variable aprobada, ya que se pasa como valor.Parámetro de matriz que pasa en C#: ¿por qué es implícitamente por referencia?

class ProgramInt 
{ 
    public static void Test(int i) // Pass by Value 
    { 
     i = 2; // Working on copy. 
    } 

    static void Main(string[] args) 
    { 
     int i = 1; 
     ProgramInt.Test(i); 
     Console.WriteLine(i); 
     Console.Read(); 

     // Output: 1 
    } 
} 

Ahora que tienen esa función de trabajo como se esperaba, se podría añadir la palabra clave ref como de costumbre:

class ProgramIntRef 
{ 
    public static void Test(ref int i) // Pass by Reference 
    { 
     i = 2; // Working on reference. 
    } 

    static void Main(string[] args) 
    { 
     int i = 1; 
     ProgramInt.Test(ref i); 
     Console.WriteLine(i); 
     Console.Read(); 

     // Output: 2 
    } 
} 

Ahora estoy perplejo en cuanto a por qué los miembros de la matriz cuando se pasa de funciones se transmiten implícitamente referencia. ¿No son los tipos de valores de matrices?

class ProgramIntArray 
{ 
    public static void Test(int[] ia) // Pass by Value 
    { 
     ia[0] = 2; // Working as reference? 
    } 

    static void Main(string[] args) 
    { 
     int[] test = new int[] { 1 }; 
     ProgramIntArray.Test(test); 
     Console.WriteLine(test[0]); 
     Console.Read(); 

     // Output: 2 
    } 
} 
+3

¿Por qué hacer una wiki? – jsmith

Respuesta

16

No, las matrices son clases, lo que significa que son tipos de referencia.

+0

Normalmente, puede presionar F12 en cualquier tipo para averiguarlo. Si la declaración dice "clase", es un tipo de referencia; si dice "struct", es un tipo de valor.Desafortunadamente, no te permite hacer esto con arreglos, lo cual es una pena. Así que solo tiene que recordar que las matrices son tipos de referencia, incluso si se trata de una matriz de un tipo de valor. – Timwi

+0

Claro y conciso, gracias. – Lazlo

+0

Para agregar a lo que dijo Timwi, F12 es la tecla rápida para Visual Studio. –

1

¿Te imaginas pasar una matriz de 2 millones de elementos por valor? Ahora imagine que el tipo de elemento es decimal. Deberá copiar alrededor de 240MB 30.5175781MB de datos.

0

Como se indica por the MSDN reference, las matrices son objetos (System.Array es el tipo de base abstracta de todas las matrices de) y los objetos se pasan por referencia.

+3

Iba a mencionar 'System.Array', pero luego recordé que' System.ValueType' y 'System.Enum' también son tipos de referencia y, sin embargo, los tipos de valores y enumeraciones que lógicamente derivan de ellos no lo son. – Timwi

2

Las matrices no se pasan por referencia. Las referencias a las matrices se pasan por valor. Si es necesario cambiar a qué matriz apunta una variable de matriz transferida (por ejemplo, para cambiar el tamaño de la matriz), la variable se debe pasar por referencia.

0

Aparte de los tipos de datos básicos no se puede pasar nada más que pasar por valor, Array es una colección de tipos básicos de datos que también permite pasar por valor en la colección crearía copias múltiples de la colección que sería malo para el rendimiento.

+2

Las estructuras no son "tipos de datos básicos" y se pasan por valor. –

2

Una buena manera de recordar esto es:

  • "ref" hace un alias a una variable de
  • una matriz es una colección de variables ; cada elemento es una variable.

Cuando se pasa una matriz normalmente, está de paso una colección de variables. Las variables en la colección no cambian.

Cuando pasa una matriz con "ref", entonces es dando un nuevo nombre a la variable que contiene la matriz.

Cuando pasa un elemento de matriz normalmente está pasando el valor en la variable.

Cuando pasa un elemento de matriz - una variable - con "ref", usted es dando un nuevo nombre a esa variable.

¿Tiene sentido?

+0

Personalmente, me gusta esto diciendo direcciones pero la mayoría de las personas aún no lo entiende. Esta es una forma en que lo describí usando un perro como una analogía, pero parece realmente cojo: http://stackoverflow.com/questions/3366650/does-var-onload-mean-that-it-should-run-when-page -is-loaded/3366783 # 3366783 – ChaosPandion

+0

Personalmente, no me gusta el fraseo de "dar un nuevo nombre". Por alguna razón, simplemente no me suena. Pero no sé cómo los principiantes lo percibirían. – Timwi

Cuestiones relacionadas