Gewusst wie: Unterschiede zwischen dem Übergeben einer Struktur und dem Übergeben eines Klassenverweises an eine Methode (C#-Programmierhandbuch)

Das folgende Beispiel stellt dar, wie die Übergabe einer Struktur an eine Methode sich von der Übergabe einer Klasseninstanz an eine Methode unterscheidet. Im Beispiel werden beide Argumente (Struktur und Klasseninstanz) nach Wert übergeben, und beide Methoden ändern den Wert eines Felds des Arguments. Allerdings sind die Ergebnisse der beiden Methoden nicht identisch, denn wenn Sie eine Struktur übergeben, unterscheidet sich dies von dem, wenn Sie eine Instanz einer Klasse übergeben.

Da eine Struktur ein Werttyp ist, wenn Sie eine Struktur nach Wert an eine Methode übergeben, erhält und funktioniert die Methode nur mit einer Kopie des Strukturarguments. Die Methode hat keinen Zugriff auf die ursprüngliche Struktur in der aufrufenden Methode und kann sie deshalb nicht ändern. Die Methode kann nur die Kopie ändern.

Eine Instanz der Klasse ist ein Verweistyp, kein Werttyp. Wenn ein Verweistyp als Wert an eine Methode übergeben wird, erhält die Methode eine Kopie des Verweises auf die Klasseninstanz. Die Methode erhält also eine Kopie der Adresse der Instanz, keine Kopie der Instanz selbst. Die Klasseninstanz in der aufrufenden Methode verfügt über eine Adresse, der Parameter in der aufgerufenen Methode verfügt über eine Kopie der Adresse und beide Adressen verweisen auf dasselbe Objekt. Da der Parameter nur eine Kopie der Adresse enthält, kann die aufgerufene Methode nicht die Adresse der Klasseninstanz in der aufrufenden Methode ändern. Allerdings kann die aufgerufene Methode die Adresse verwenden, um auf die Klassenmember zuzugreifen, auf die sich die ursprüngliche Adresse sowie die Kopie beziehen. Wenn die aufgerufene Methode einen Klassenmember ändert, ändert sich auch die ursprüngliche Klasseninstanz in der aufrufenden Methode.

Die Ausgabe des folgenden Beispiels veranschaulicht den Unterschied. Der Wert des Felds willIChange der Klasseninstanz wird durch den Aufruf auf die Methode ClassTaker geändert, da die Methode die Adresse im Parameter verwendet, um das angegebene Feld der Klasseninstanz zu finden. Das Feld willIChange der Struktur in der aufrufenden Methode wird nicht durch den Aufruf auf die Methode StructTaker geändert, da der Wert des Arguments eine Kopie der Struktur selbst ist und keine Kopie deren Adresse. StructTaker ändert die Kopie, und die Kopie wird abgebrochen, wenn der Aufruf auf StructTaker abgeschlossen ist.

Beispiel

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
*/

Siehe auch

C#-Programmierhandbuch
Klassen
Strukturen
Übergeben von Parametern