ref (C#-Referenz)ref (C# Reference)

Das ref-Schlüsselwort gibt einen Wert an, der als Verweis übergeben wird.The ref keyword indicates a value that is passed by reference. Es wird in drei unterschiedlichen Kontexten verwendet:It is used in three different contexts:

  • In einer Methodensignatur und in einem Methodenaufruf, um ein Argument an eine Methode als Verweis zu übergeben.In a method signature and in a method call, to pass an argument to a method by reference. Weitere Informationen finden Sie unter Passing an argument by reference (Übergeben eines Arguments als Verweis).See Passing an argument by reference for more information.

  • In einer Methodensignatur, um einen Wert an den Aufrufer als Verweis zurückzugeben.In a method signature, to return a value to the caller by reference. Weitere Informationen finden Sie unter Verweisrückgabewerte.See Reference return values for more information.

  • In einem Memberkörper, um anzugeben, dass ein Verweisrückgabewert lokal als Verweis, den der Aufrufer ändern möchte, gespeichert wird.In a member body, to indicate that a reference return value is stored locally as a reference that the caller intends to modify. Weitere Informationen finden Sie unter Lokale ref-Variablen.See Ref locals for more information.

Übergeben eines Arguments als VerweisPassing an argument by reference

In der Parameterliste einer Methode gibt das ref-Schlüsselwort an, dass ein Argument als Verweis und nicht als Wert übergeben wird.When used in a method's parameter list, the ref keyword indicates that an argument is passed by reference, not by value. Durch das Übergeben als Verweis wird jede Änderung am Argument in der aufgerufenen Methode in der aufrufenden Methode wiedergegeben.The effect of passing by reference is that any change to the argument in the called method is reflected in the calling method. Wenn der Aufrufer z.B. 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, wenn die Methode zurückgibt.For example, if the caller passes a local variable expression or an array element access expression, and the called method replaces the object to which the ref parameter refers, then the caller’s local variable or the array element now refers to the new object when the method returns.

Hinweis

Verwechseln Sie nicht das Konzept der Übergabe durch einen Verweis mit dem Konzept der Verweistypen.Do not confuse the concept of passing by reference with the concept of reference types. Die beiden Konzepte sind nicht identisch.The two concepts are not the same. Ein Methodenparameter kann durch ref geändert werden, unabhängig davon, ob es sich um einen Werttyp oder ein Verweistyp handelt.A method parameter can be modified by ref regardless of whether it is a value type or a reference type. Es gibt keine Boxing-Konvertierung eines Werttyps, wenn er durch einen Verweis übergeben wird.There is no boxing of a value type when it is passed by reference.

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.To use a ref parameter, both the method definition and the calling method must explicitly use the ref keyword, as shown in the following example.

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.An argument that is passed to a ref parameter must be initialized before it is passed. Dies unterscheidet sich von den out-Parametern, deren Argumente nicht explizit initialisiert werden müssen, bevor sie übergeben werden.This differs from out parameters, whose arguments do not have to be explicitly initialized before they are passed.

Member einer Klasse können keine Signaturen haben, die sich nur durch ref und out voneinander unterscheiden.Members of a class can't have signatures that differ only by ref and out. 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.A compiler error occurs if the only difference between two members of a type is that one of them has a ref parameter and the other has an out parameter. Der folgende Code wird z. B. nicht kompiliert.The following code, for example, doesn't compile.

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 können Methoden überladen werden, wenn eine Methode einen ref- oder out-Parameter hat und die andere über einen Werteparameter verfügt, wie im folgenden Beispiel gezeigt.However, methods can be overloaded when one method has a ref or out parameter and the other has a value parameter, as shown in the following example.

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.In other situations that require signature matching, such as hiding or overriding, ref and out are part of the signature and don't match each other.

Eigenschaften sind keine Variablen.Properties are not variables. Sie sind Methoden und können nicht an ref-Parameter übergeben werden.They are methods, and cannot be passed to ref parameters.

Weitere Informationen zum Übergeben von Arrays finden Sie unter Übergeben von Arrays mithilfe von „ref“ und „out“.For information about how to pass arrays, see Passing Arrays Using ref and out.

Sie können keines der beiden Schlüsselwörter ref und out für die folgenden Methodentypen verwenden:You can't use the ref and out keywords for the following kinds of methods:

  • Asynchrone Methoden, die Sie mit dem async-Modifizierer definieren.Async methods, which you define by using the async modifier.

  • Iterator-Methoden, die eine yield return- oder yield break-Anweisung enthalten.Iterator methods, which include a yield return or yield break statement.

Übergeben eines Arguments als Verweis: BeispielPassing an argument by reference: An example

In den vorherigen Beispielen wurden Werttypen als Verweis übergeben.The previous examples pass value types by reference. Sie können das ref-Schlüsselwort auch verwenden, um Verweistypen als Verweis zu übergeben.You can also use the ref keyword to pass reference types by reference. Die Übergabe eines Verweistyps als Verweis ermöglicht es der aufgerufenen Methode, das Objekt, auf die der Verweisparameter im Aufrufer verweist, zu ersetzen.Passing a reference type by reference enables the called method to replace the object to which the reference parameter refers in the caller. Der Speicherort des Objekts wird als Wert des Verweisparameters an die Methode übergeben.The storage location of the object is passed to the method as the value of the reference parameter. 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.If you change the value in the storage location of the parameter (to point to a new object), you also change the storage location to which the caller refers. Im folgenden Beispiel wird eine Instanz eines Verweistyps als ein ref-Parameter übergeben.The following example passes an instance of a reference type as a ref parameter.

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

Weitere Informationen zum Übergeben von Verweistypen durch einen Wert und durch einen Verweis finden Sie unter Übergeben von Verweistypparametern.For more information about how to pass reference types by value and by reference, see Passing Reference-Type Parameters.

VerweisrückgabewerteReference return values

Verweisrückgabewerte (auch ref-Rückgaben genannt) sind Werte, die von einer Methode an den Aufrufer als Verweis zurückgegeben werden.Reference return values (or ref returns) are values that a method returns by reference to the caller. Das bedeutet, dass der Aufrufer den von einer Methode zurückgegebenen Wert ändern kann. Diese Änderung wird im Zustand des Objekts, das die Methode enthält, wiedergegeben.That is, the caller can modify the value returned by a method, and that change is reflected in the state of the object that contains the method.

Ein Verweisrückgabewert wird definiert durch Verwenden des ref-Schlüsselworts:A reference return value is defined by using the ref keyword:

  • In der Methodensignatur.In the method signature. Die folgende Methodensignatur gibt z.B. an, dass die Methode GetCurrentPrice den Wert Decimal als Verweis zurückgibt.For example, the following method signature inidicates that the GetCurrentPrice method returns a Decimal value by reference.

    public ref decimal GetCurrentValue()
    
  • Vor jeder return-Anweisung in der Methode.Before each return statement in the method. Zum Beispiel:For example:

    ref return Decimal.Zero;
    

In der Reihenfolge für den Aufrufer zum Ändern des Zustands des Objekts, den Verweis zurückzugeben Wert muss gespeichert werden, um eine Variable, die als explizit definiert ist ein Ref lokale.In order for the caller to modify the object's state, the reference return value must be stored to a variable that is explicitly defined as a ref local.

Ein Beispiel finden Sie unter Beispiel für ref-Rückgaben und lokale ref-Variablen.For an example, see A ref returns and ref locals example

Lokale ref-VariablenRef locals

Eine lokale ref-Variable wird verwendet, um auf Werte zu verweisen, die mit ref return zurückgegeben werden.A ref local variable is used to refer to values returned using ref return. Eine lokale ref-Variable muss initialisiert und einem ref-Rückgabewert zugewiesen werden.A ref local variable must be initialized and assigned to a ref return value. Jede Änderung am Wert der lokalen ref-Variable wird im Zustand des Objekts wiedergegeben, dessen Methode den Wert als Verweis zurückgegeben hat.Any modifications to the value of the ref local are reflected in the state of the object whose method returned the value by reference.

Eine lokale ref-Variable wird mithilfe des ref-Schlüsselworts vor der Variablendeklaration definiert sowie unmittelbar vor dem Aufruf der Methode, die den Wert als Verweis zurückgibt.You define a ref local by using the ref keyword before the variable declaration, as well as immediately before the call to the method that returns the value by reference.

Die folgende Anweisung definiert z.B. eine lokale ref-Variable, die von der Methode GetEstimatedValue zurückgegeben wird:For example, the following statement defines a ref local value that is returned by a method named GetEstimatedValue:

ref decimal estValue = ref Building.GetEstimatedValue();

Beachten Sie, dass das ref-Schlüsselwort an beiden Stellen verwendet werden muss. Andernfalls generiert der Compiler den Fehler CS8172 „Eine by-reference-Variable kann nicht mit einem Wert initialisiert werden“.Note that the ref keyword must be used in both places, or the compiler generates error CS8172, "Cannot initialize a by-reference variable with a value."

Beispiel für ref-Rückgaben und lokale ref-VariablenA ref returns and ref locals example

Im folgenden Beispiel wird eine Book-Klasse mit zwei String-Feldern definiert: Title und Author.The following example defines a Book class that has two String fields, Title and Author. Außerdem wird eine BookCollection-Klasse definiert, die ein privates Array von Book-Objekten enthält.It also defines a BookCollection class that includes a private array of Book objects. Einzelne Buchobjekte werden durch Aufrufen der GetBookByTitle-Methode als Verweis zurückgegeben.Individual book objects are returned by reference by calling its GetBookByTitle method.

using System;

public class Book
{
   public string Author;
   public string Title;
}

public class BookCollection
{
   private Book[] books = { new Book { Title = "Call of the Wild, The", Author = "Jack London" },
                            new Book { Title = "Tale of Two Cities, A", Author = "Charles Dickens" }  
                           };
   private Book nobook = null;

   public ref Book GetBookByTitle(string title)
   {
      for (int ctr = 0; ctr < books.Length; ctr++)
      {
         if (title == books[ctr].Title)
            return ref books[ctr];
      }
      return ref nobook;
   }

   public void ListBooks()
   {
      foreach (var book in books) {
         Console.WriteLine($"{book.Title}, by {book.Author}");
      }
      Console.WriteLine();   
   } 
}

Speichert der Aufrufer den von der GetBookByTitle-Methode zurückgegeben Wert als lokale ref-Variable, werden Änderungen, die der Aufrufer am Rückgabewert vornimmt, im BookCollection-Objekt wiedergegeben. Dies wird im folgenden Beispiel gezeigt:When the caller stores the value returned by the GetBookByTitle method as a ref local, changes that the caller makes to the return value are reflected in the BookCollection object, as the following example shows.

using System;

class Example
{
   static void Main()
   {
      var bc = new BookCollection();
      bc.ListBooks();
      
      ref var book = ref bc.GetBookByTitle("Call of the Wild, The");
      if (book != null)
         book = new Book { Title = "Republic, The", Author = "Plato" };
      bc.ListBooks();
   }
}
// The example displays the following output:
//       Call of the Wild, The, by Jack London
//       Tale of Two Cities, A, by Charles Dickens
//       
//       Republic, The, by Plato
//       Tale of Two Cities, A, by Charles Dickens

C#-ProgrammiersprachenspezifikationC# Language Specification

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

Siehe auchSee Also

C#-ReferenzC# Reference
C#-ProgrammierhandbuchC# Programming Guide
Übergeben von ParameternPassing Parameters
MethodenparameterMethod Parameters
C#-SchlüsselwörterC# Keywords