Pasar parámetros Reference-Type (Guía de programación de C#)

Actualización: noviembre 2007

Una variable de un tipo de referencia no contiene directamente sus datos; contiene una referencia a ellos. Cuando se pasa un parámetro de tipo de referencia por valor, es posible cambiar los datos a los que apunta la referencia, como el valor de un miembro de clase. Sin embargo, no se puede cambiar el valor de la propia referencia; es decir, no se puede utilizar la misma referencia para asignar memoria a una nueva clase y hacer que persista fuera del bloque. Para hacer esto, se debe pasar el parámetro mediante la palabra clave ref u out. Para simplificar, los siguientes ejemplos utilizan ref.

Ejemplo

El siguiente ejemplo ilustra el paso de un parámetro de tipo de referencia, arr, por valor, a un método, Change. Como el parámetro es una referencia a arr, es posible cambiar los valores de los elementos de la matriz. Sin embargo, el intento de volver a asignar el parámetro a otra ubicación de memoria sólo funciona dentro del método y no afecta a la variable original, arr.

class PassingRefByVal 
{
    static void Change(int[] pArray)
    {
        pArray[0] = 888;  // This change affects the original element.
        pArray = new int[5] {-3, -1, -2, -3, -4};   // This change is local.
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main() 
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);

        Change(arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
    }
}
/* Output:
    Inside Main, before calling the method, the first element is: 1
    Inside the method, the first element is: -3
    Inside Main, after calling the method, the first element is: 888
*/

En el ejemplo anterior, la matriz arr, que es un tipo de referencia, se pasa al método sin el parámetro ref. En ese caso, lo que se pasa al método es una copia de la referencia, la cual apunta a arr. El resultado muestra cómo el método puede cambiar el contenido de un elemento de la matriz, en este caso de 1 a 888. Sin embargo, cuando se asigna una nueva porción de memoria mediante el operador new dentro del método Change, la variable pArray hace referencia a una nueva matriz. De este modo, cualquier cambio posterior no afectará a la matriz original, arr, que se crea dentro de Main. De hecho, en este ejemplo se crean dos matrices, una dentro de Main y otra dentro del método Change.

Este ejemplo es el mismo que el ejemplo anterior, excepto que utiliza la palabra clave ref en el encabezado del método y en la llamada. Cualquier cambio que se realice en el método afectará a las variables originales del programa que hace la llamada.

class PassingRefByRef 
{
    static void Change(ref int[] pArray)
    {
        // Both of the following changes will affect the original variables:
        pArray[0] = 888;
        pArray = new int[5] {-3, -1, -2, -3, -4};
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main() 
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr[0]);

        Change(ref arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr[0]);
    }
}
/* Output:
    Inside Main, before calling the method, the first element is: 1
    Inside the method, the first element is: -3
    Inside Main, after calling the method, the first element is: -3
*/

Todos los cambios que tienen lugar dentro del método afectan a la matriz original en Main. De hecho, la matriz original se reasigna mediante el operador new. De esta forma, después de llamar al método Change, cualquier referencia a arr apunta a la matriz de cinco elementos que se crea en el método Change.

El intercambio de cadenas constituye un buen ejemplo de paso de parámetros de tipo de referencia por referencia. En el ejemplo, se inicializan dos cadenas, str1 y str2, en Main y se pasan al método SwapStrings como parámetros modificados por la palabra clave ref. Las dos cadenas se intercambian dentro del método y también dentro de Main.

 class SwappingStrings
 {
     static void SwapStrings(ref string s1, ref string s2)
     // The string parameter is passed by reference.
     // Any changes on parameters will affect the original variables.
     {
         string temp = s1;
         s1 = s2;
         s2 = temp;
         System.Console.WriteLine("Inside the method: {0} {1}", s1, s2);
     }

     static void Main()
     {
         string str1 = "John";
         string str2 = "Smith";
         System.Console.WriteLine("Inside Main, before swapping: {0} {1}", str1, str2);

         SwapStrings(ref str1, ref str2);   // Passing strings by reference
         System.Console.WriteLine("Inside Main, after swapping: {0} {1}", str1, str2);
     }
 }
 /* Output:
     Inside Main, before swapping: John Smith
     Inside the method: Smith John
     Inside Main, after swapping: Smith John
*/

En este ejemplo, los parámetros se deben pasar por referencia para que afecten a las variables del programa que realiza la llamada. Si se quita la palabra clave ref del encabezado del método y de la llamada al método, no se producirá ningún cambio en el programa que realiza la llamada.

Para obtener más información sobre las cadenas, vea string.

Vea también

Conceptos

Guía de programación de C#

Referencia

Pasar parámetros (Guía de programación de C#)

Pasar matrices mediante Ref y Out (Guía de programación de C#)

ref (Referencia de C#)

Tipos de referencia (Referencia de C#)