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

Una variable de un tipo de referencia no contiene sus datos directamente, contiene una referencia a sus datos.A variable of a reference type does not contain its data directly; it contains a reference to its data. Al pasar un parámetro de tipo de referencia por valor, es posible cambiar los datos que pertenecen al objeto al que se hace referencia, como el valor de un miembro de clase.When you pass a reference-type parameter by value, it is possible to change the data belonging to the referenced object, such as the value of a class member. En cambio, no se puede cambiar el valor de la propia referencia; por ejemplo, no puede usar la misma referencia para asignar memoria para un nuevo objeto y hacer que persista fuera del método.However, you cannot change the value of the reference itself; for example, you cannot use the same reference to allocate memory for a new object and have it persist outside the method. Para ello, pase el parámetro mediante las palabras clave ref u out.To do that, pass the parameter using the ref or out keyword. Para simplificar, en el ejemplo siguiente se usa ref.For simplicity, the following examples use ref.

Pasar tipos de referencia en función del valorPassing Reference Types by Value

En el ejemplo siguiente, se muestra cómo pasar un parámetro de tipo de referencia, arr, en función del valor a un método, Change.The following example demonstrates passing a reference-type parameter, arr, by value, to a method, Change. Dado que el parámetro es una referencia a arr, es posible cambiar los valores de los elementos de matriz.Because the parameter is a reference to arr, it is possible to change the values of the array elements. En cambio, el intento de volver a asignar el parámetro a otra ubicación de memoria solo funciona dentro del método y no afecta a la variable original, arr.However, the attempt to reassign the parameter to a different memory location only works inside the method and does not affect the original variable, 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.In the preceding example, the array, arr, which is a reference type, is passed to the method without the ref parameter. En tal caso, se pasa al método una copia de la referencia, que apunta a arr.In such a case, a copy of the reference, which points to arr, is passed to the method. El resultado muestra que es posible que el método cambie el contenido de un elemento de matriz, en este caso de 1 a 888.The output shows that it is possible for the method to change the contents of an array element, in this case from 1 to 888. En cambio, si se asigna una nueva porción de memoria al usar el operador new dentro del método Change, la variable pArray hace referencia a una nueva matriz.However, allocating a new portion of memory by using the new operator inside the Change method makes the variable pArray reference a new array. Por tanto, cualquier cambio que hubiese después no afectará a la matriz original, arr, que se ha creado dentro de Main.Thus, any changes after that will not affect the original array, arr, which is created inside Main. De hecho, se crean dos matrices en este ejemplo, una dentro de Main y otra dentro del método Change.In fact, two arrays are created in this example, one inside Main and one inside the Change method.

Pasar tipos de referencia en función de la referenciaPassing Reference Types by Reference

El ejemplo siguiente es el mismo que el anterior, salvo que la palabra clave ref se agrega a la llamada y al encabezado de método.The following example is the same as the previous example, except that the ref keyword is added to the method header and call. Los cambios que tengan lugar en el método afectan a la variable original en el programa que realiza la llamada.Any changes that take place in the method affect the original variable in the calling program.

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.All of the changes that take place inside the method affect the original array in Main. De hecho, la matriz original se reasigna mediante el operador new.In fact, the original array is reallocated using the new operator. Por tanto, 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.Thus, after calling the Change method, any reference to arr points to the five-element array, which is created in the Change method.

Intercambiar dos cadenasSwapping Two Strings

Intercambiar cadenas es un buen ejemplo de pasar parámetros de tipo de referencia en función de la referencia.Swapping strings is a good example of passing reference-type parameters by reference. 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.In the example, two strings, str1 and str2, are initialized in Main and passed to the SwapStrings method as parameters modified by the ref keyword. Las dos cadenas se intercambian dentro del método y también dentro de Main.The two strings are swapped inside the method and inside Main as well.

 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 tienen que pasarse en función de la referencia para afectar a las variables en el programa que realiza la llamada.In this example, the parameters need to be passed by reference to affect the variables in the calling program. Si quita la palabra clave ref tanto del encabezado de método como de la llamada al método, no se llevará a cabo ningún cambio en el programa que realiza la llamada.If you remove the ref keyword from both the method header and the method call, no changes will take place in the calling program.

Para obtener más información sobre las cadenas, vea string.For more information about strings, see string.

Vea tambiénSee also