Nivel 3 — Funciones
Paso por valor frente a paso por referencia
Notas originales de SunDiaL · Ver fuente en inglés
Segunda parte de esta saga confusa. Los parámetros también se dividen en dos categorías que, combinadas con los tipos de valor y los tipos de referencia, dan un total de cuatro combinaciones.
Paso por valor
Esta es la forma estándar de pasar parámetros. A la variable del parámetro se le asigna una copia del valor.
- Para los tipos de valor, esto significa que se copia el propio valor.
- Para los tipos de referencia, esto significa que se copia la dirección del objeto. Es lo mismo que pasar por puntero en C++.
Paso por referencia
La otra forma de pasar parámetros.
- En este caso, el objeto se utiliza «directamente».
Es lo mismo que pasar por referencia en C++; sin embargo, las referencias en C# no son exactamente lo mismo que las referencias en C++.
Para una explicación más detallada sobre las referencias de C++, consulta Puntero frente a referencia.
Es difícil de explicar sin verlo en acción, y para eso hace falta conocer las clases, así que vuelve a estos ejemplos más adelante.
Ejemplos
1. Tipo de valor por valor
void ByVal(int x)
{
x++;
Console.WriteLine(x);
}
void Main()
{
int x = 1;
ByVal(x); // will print 2
Console.WriteLine(x); //will print 1, because there are now two "1" objects sitting in memory. One for the x in main, and one for the x in ByVal.
}
2. Tipo de valor por referencia
void ByRef(ref int x)
{
x++;
Console.WriteLine(x);
}
void Main()
{
int x = 1;
ByVal(ref x); // will print 2
Console.WriteLine(x); //will print 2, because x in ByRef uses the the object itself, not a copy.
}
3. Tipo de referencia por valor
class Test
{
public int val;
}
void ByValIncrement(Test x)
{
x.val++
Console.WriteLine(x.val);
}
void ByValIncrement(Test x)
{
x = new Test();
x.val = 3;
Console.WriteLine(x.val);
}
void Main()
{
Test x = new Test();
x.val = 1;
ByValIncrement(x); // will print 2
Console.WriteLine(x.val); //will print 2, because the same address was used.
ByValChange(x) //will print 3.
Console.WriteLine(x.val); //will print 2, because the object was changed inside the function.
}
4. Tipo de referencia por referencia
class Test
{
public int val;
}
void ByValIncrement(ref Test x)
{
x.val++
Console.WriteLine(x.val);
}
void ByValIncrement(ref Test x)
{
x = new Test();
x.val = 3;
Console.WriteLine(x.val);
}
void Main()
{
Test x = new Test();
x.val = 1;
ByValIncrement(ref x); // will print 2
Console.WriteLine(x.val); //will print 2, because the same object was used.
ByValChange(ref x) //will print 3.
Console.WriteLine(x.val); //will print 3, because the object was used "directly".
}