Parámetros por valor y referencia

1  - parámetros por valor

Cuando tenemos un método le pasamos un parámetro, en verdad no estamos mandando ese parámetro, estamos mandado una copia de este, lo que significa, que fuera del método, el valor de la variable seguirá siendo el mismo. Incluso si modificamos su valor internamente.

static void Main(string[] args)
{
    int valorActual = 10;

    Actualizar(valorActual); 
    Console.WriteLine($"el valor es: {valorActual}");//imprime 10

    Console.ReadKey();
}

//Comportamiento normal.
public static void Actualizar(int valor)
{
    valor += 5;
    Console.WriteLine($"el valor es: {valor}"); //imprime 15
}

valorActual sigue valiendo 10 después de finalizar el método Actualizar() ya que el valor únicamente se modifica para ese método.

2 - Parámetros por referencia

Puede llegar el momento de que necesitemos actualizar el valor de los datos. Para ello pasaremos los parámetros por referencia, y lo haremos utilizando las palabras reservadas ref y out. Cuando utilizamos ref y out no almacenamos en la variable el valor de esta, sino que almacenamos la posición de memoria a la que apunta por lo que, si modificamos el valor, también cambiamos el valor de la original. 

2.1 - Palabra reservada ref

Utilizar ref significa que vas a pasar el valor por referencia a un método, lo que implica que el valor va a cambiar dentro del método. Además, si deseamos utilizar ref la variable tiene que estar inicializada con anterioridad.

Finalmente debemos indicar tanto en el método como en la llamada al método que vamos a pasar un valor por referencia.

static void Main(string[] args)
{
    int valorActual = 10;

    ActualizarRef(ref valorActual); //pasar por referencia
    Console.WriteLine($"el valor es: {valorActual}"); // imprime 12

  
    Console.ReadKey();
}

//Actualizar por referencia
public static void ActualizarRef(ref int valor)
{
    valor += 2;
}

 

2.2 - Palabra reservada out

Utilizar out significa que la asignación del valor de esa variable está dentro del método al que se llama. No es necesario inicializar el valor de la variable, aunque si debemos instanciarla.

static void Main(string[] args)
{

    int valorActual;
    ActualizarOut(out valorActual);
    Console.WriteLine($"el valor es: {valorActual}"); // imprime 13

    Console.ReadKey();
}


//Crear utilizando out
public static void ActualizarOut(out int valor)
{
    valor = 13;
}

2.3 - Palabra reservada In

 

La palabra clave in evita que podamos modificar el valor de la variable dentro del método, por lo que el valor siempre será el que hayamos pasado previamente.

public static void ActualizarIn(in int valor)
{
    valor += 5; //Da Error 
    Console.WriteLine($"el valor es: {valor}");
}

 

3 - El caso especial de objetos

Cuando pasamos un Objeto/Tipo creado por nosotros mismos, este siempre se pasa por referencia. Con lo que, si lo actualizamos dentro de la función, se actualizara fuera de ella.

class Program
{
    static void Main(string[] args)
    {
        
        ObjEjemplo ejemploValor = new ObjEjemplo(10);
        ActualizarObj(ejemploValor);
        Console.WriteLine($"el valor es: {ejemploValor.Entero}"); // imprime 25

        Console.ReadKey();
    }

    public static void ActualizarObj(ObjEjemplo obj)
    {
        obj.Entero = 25;
    }

}

public class ObjEjemplo
{
    public int Entero { get; set; }

    public ObjEjemplo(int entero)
    {
        Entero = entero;
    }
}

4 - Datos finales

  • Debemos utilizar ref si queremos cambiar el valor de la variable, en cambio si queremos crear una nueva variable debemos utilizar out. In cuando queramos que ese valor no se pueda modificar.
  • No podemos utilizar in, ref, out en métodos asíncronos o iteradores. 

5 - Cuando utilizar ref u out?

Utilizaremos ref u out cuando necesitemos múltiples valores de retorno de un mismo método.

Desde la llegada de .NetFramework 4.0 es mas común utilizar Tuple<T> cuando necesitamos mas de un valor de salida.

6 - Código

El código esta disponible en GitHub aquí


Soporte


2019 NetMentor.
Todos los derechos reservados.
Aviso legal | Politica privacidad | Politica de cookies