Compartir a través de


Cómo: Saber las diferencias entre pasar a un método un struct y una referencia a clase (Guía de programación de C#)

El ejemplo siguiente muestra cómo pasar struct a un método diferencia de pasar una instancia de clase a un método. En el ejemplo, los dos argumentos (struct e instancia de clase) se pasan por valor, y ambos métodos cambie el valor de un campo de argumento. Sin embargo, los resultados de los dos métodos no son iguales porque se pasan qué cuando se pasa un struct diferencia se pasa de qué cuando se pasa una instancia de una clase.

Dado que un struct es tipo de valor, al pase un struct por valor a un método, el método recibe y funciona en una copia del argumento de struct. El método no tiene ningún acceso a struct original en el método de llamada y por tanto no puede cambiarlo de ningún modo. El método sólo puede cambiar la copia.

Una instancia de clase es tipo de referencia, no un tipo de valor. cuando un tipo de referencia se pasa por valor a un método, el método recibe una copia de la referencia a la instancia de clase. Es decir, el método recibe una copia de la dirección de la instancia, no una copia de la propia instancia. La instancia de clase en el método de llamada tiene una dirección, el parámetro en el método denominado tiene una copia de la dirección, y ambas direcciones hacen referencia al mismo objeto. Dado que el parámetro contiene sólo una copia de la dirección, el método denominado no puede cambiar la dirección de la instancia de clase en el método de llamada. Sin embargo, el método denominado puede utilizar la dirección para obtener acceso a los miembros de clase que tanto la dirección original y la copia hace referencia. Si el método denominado cambia a un miembro de clase, la instancia de clase original en la llamada del método los cambios también.

El resultado del ejemplo siguiente muestra la diferencia. El valor del campo de willIChange de la instancia de clase se cambia por la llamada al método ClassTaker porque el método utiliza la dirección del parámetro para encontrar el campo especificado de la instancia de clase. El campo de willIChange struct en el método de llamada no se cambia por la llamada al método StructTaker porque el valor del argumento es una copia del struct propia, no una copia de la dirección. StructTaker cambia la copia, y se perderá la copia cuando la llamada a StructTaker se completa.

Ejemplo

class TheClass
{
    public string willIChange;
}

struct TheStruct
{
    public string willIChange;
}

class TestClassAndStruct
{
    static void ClassTaker(TheClass c)
    {
        c.willIChange = "Changed";
    }

    static void StructTaker(TheStruct s)
    {
        s.willIChange = "Changed";
    }

    static void Main()
    {
        TheClass testClass = new TheClass();
        TheStruct testStruct = new TheStruct();

        testClass.willIChange = "Not Changed";
        testStruct.willIChange = "Not Changed";

        ClassTaker(testClass);
        StructTaker(testStruct);

        Console.WriteLine("Class field = {0}", testClass.willIChange);
        Console.WriteLine("Struct field = {0}", testStruct.willIChange);

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Class field = Changed
    Struct field = Not Changed
*/

Vea también

Referencia

Clases (Guía de programación de C#)

Structs (Guía de programación de C#)

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

Conceptos

Guía de programación de C#