ref (C#-Referenz)

Das Schlüsselwort ref bewirkt, dass ein Argument durch einen Verweis, nicht durch einen Wert übergeben wird. Durch das Übergeben durch einen Verweis wird jede Änderung am Parameter in der aufgerufenen Methode in der aufrufenden Methode wiedergegeben. Wenn z. B. der Aufrufer einen lokalen Variablenausdruck oder einen Arrayelement-Zugriffsausdruck übergibt und die aufgerufene Methode das Objekt ersetzt, auf das der Ref-Parameter verweist, dann verweist die lokale Variable des Aufrufers oder das Arrayelement jetzt auf das neue Objekt.

Hinweis

Verwechseln Sie nicht das Konzept der Übergabe durch einen Verweis mit dem Konzept der Verweistypen. Die beiden Konzepte sind nicht identisch. Ein Methodenparameter kann durch ref geändert werden, unabhängig davon, ob es sich um einen Werttyp oder ein Verweistyp handelt. Es gibt keine Boxing-Konvertierung eines Werttyps, wenn er durch einen Verweis übergeben wird.

Um einen ref-Parameter zu verwenden, müssen sowohl die Methodendefinition als auch die aufrufende Methode explizit das Schlüsselwort ref verwenden, wie im folgenden Beispiel gezeigt.

class RefExample
{
    static void Method(ref int i)
    {
        i = i + 44;
    }

    static void Main()
    {
        int val = 1;
        Method(ref val);
        Console.WriteLine(val);
        // Output: 45
    }
}

Ein Argument, das an einen ref-Parameter übergeben wird, muss vor der Übergabe initialisiert werden. Dies unterscheidet sich von den out-Parametern, deren Argumente nicht explizit initialisiert werden müssen, bevor sie übergeben werden. Weitere Informationen finden Sie unter out.

Member einer Klasse können keine Signaturen haben, die sich nur durch ref und out voneinander unterscheiden. Es tritt ein Compilerfehler auf, wenn der einzige Unterschied zwischen beiden Member eines Typs der ist, dass einer von ihnen über einen ref-Parameter und der andere über einen out-Parameter verfügt. Der folgende Code wird z. B. nicht kompiliert.

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

Allerdings ist eine Überladung möglich, wenn eine Methode einen ref- oder out-Parameter hat und die andere über einen Werteparameter verfügt, wie im folgenden Beispiel gezeigt.

class RefOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(ref int i) { }
}

In anderen Situationen, die eine Signaturabstimmung benötigen, z. B. beim Ausblenden oder Überschreiben, sind ref und out Bestandteil der Signatur und passen nicht zueinander.

Eigenschaften sind keine Variablen. Sie sind Methoden und können nicht an ref-Parameter übergeben werden.

Weitere Informationen zum Übergeben von Arrays finden Sie unter Übergeben von Arrays mithilfe von „ref“ und „out“.

Sie können keines der beiden Schlüsselwörter ref und out für die folgenden Methodentypen verwenden:

  • Async-Methoden, die Sie mit dem async-Modifizierer definieren.

  • Iterator-Methoden, die eine yield return- oder yield break-Anweisung enthalten.

Beispiel

Die vorherigen Beispiele zeigen, was passiert, wenn Sie Werttypen durch einen Verweis übergeben. Sie können auch das Schlüsselwort ref verwenden, um Verweistypen zu übergeben. Die Übergabe eines Verweistyps durch einen Verweis ermöglicht es der aufgerufenen Methode, das Objekt in der aufrufenden Methode, auf die der Verweisparameter verweist, zu ersetzen. Der Speicherort des Objekts wird als Wert des Verweisparameters an die Methode übergeben. Wenn Sie den Wert am Speicherort des Parameters ändern (um auf ein neues Objekt zu verweisen), ändern Sie auch den Speicherort, auf den der Aufrufer verweist. Im folgenden Beispiel wird eine Instanz eines Verweistyps als ein ref-Parameter übergeben. Weitere Informationen zum Übergeben von Verweistypen durch einen Wert und durch einen Verweis finden Sie unter Übergeben von Verweistypparametern.

class RefExample2
{
    static void Main()
    {
        // Declare an instance of Product and display its initial values.
        Product item = new Product("Fasteners", 54321);
        System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}\n",
            item.ItemName, item.ItemID);

        // Pass the product instance to ChangeByReference.
        ChangeByReference(ref item);
        System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n",
            item.ItemName, item.ItemID);
    }

    static void ChangeByReference(ref Product itemRef)
    {
        // Change the address that is stored in the itemRef parameter.   
        itemRef = new Product("Stapler", 99999);

        // You can change the value of one of the properties of
        // itemRef. The change happens to item in Main as well.
        itemRef.ItemID = 12345;
    }
}

class Product
{
    public Product(string name, int newID)
    {
        ItemName = name;
        ItemID = newID;
    }

    public string ItemName { get; set; }
    public int ItemID { get; set; }
}
// Output: 
//        Original values in Main.  Name: Fasteners, ID: 54321
//    
//        Back in Main.  Name: Stapler, ID: 12345

C#-Programmiersprachenspezifikation

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

C#-Referenz
C#-Programmierhandbuch
Übergeben von Parametern
Methodenparameter

C#-Schlüsselwörter