Freigeben über


Deklarationsanweisungen

Eine Deklarationsanweisung deklariert eine neue lokale Variable, eine lokale Konstante oder eine lokale Verweisvariable.

Die C#-Sprachreferenz dokumentiert die zuletzt veröffentlichte Version der C#-Sprache. Außerdem enthält sie erste Dokumentation für Features in der öffentlichen Vorschau für die kommende Sprachversion.

In der Dokumentation werden alle Features identifiziert, die in den letzten drei Versionen der Sprache oder in der aktuellen öffentlichen Vorschau eingeführt wurden.

Tipp

Informationen dazu, wann ein Feature erstmals in C# eingeführt wurde, finden Sie im Artikel zum Versionsverlauf der C#-Sprache.

Um eine lokale Variable zu deklarieren, geben Sie ihren Typ und ihren Namen an. Sie können mehrere Variablen desselben Typs in einer Anweisung deklarieren, wie das folgende Beispiel zeigt:

string greeting;
int a, b, c;
List<double> xs;

Sie können eine Variable in einer Deklarationsanweisung auch mit einem Anfangswert initialisieren:

string greeting = "Hello";
int a = 3, b = 2, c = a + b;
List<double> xs = new();

In den vorherigen Beispielen wurde der Typ der Variablen explizit angegeben. Sie können den Datentyp einer Variable auch durch den Compiler vom Typ des Initialisierungsausdrucks ableiten lassen. Verwenden Sie dazu das Schlüsselwort var anstelle des Namens eines Typs. Weitere Informationen finden Sie im Abschnitt Implizit typisierte lokale Variablen.

Um eine lokale Konstante zu deklarieren, verwenden Sie das Schlüsselwort const, wie im folgenden Beispiel gezeigt:

const string Greeting = "Hello";
const double MinLimit = -10.0, MaxLimit = -MinLimit;

Wenn Sie eine lokale Konstante deklarieren, müssen Sie diese auch initialisieren.

Informationen zu lokalen Verweisvariablen finden Sie im Abschnitt Verweisvariablen.

Implizit typisierte lokale Variablen

Wenn Sie eine lokale Variable deklarieren, können Sie den Typ der Variable durch den Compiler aus dem Initialisierungsausdruck ableiten lassen. Verwenden Sie dazu das var Schlüsselwort anstelle des Namens eines Typs:

var greeting = "Hello";
Console.WriteLine(greeting.GetType());  // output: System.String

var a = 32;
Console.WriteLine(a.GetType());  // output: System.Int32

var xs = new List<double>();
Console.WriteLine(xs.GetType());  // output: System.Collections.Generic.List`1[System.Double]

Wie im vorherigen Beispiel gezeigt, werden implizit typierte lokale Variablen stark typiert.

Hinweis

Wenn Sie var im aktivierten Nullwerte zulassenden Kontext verwenden und der Typ eines Initialisierungsausdrucks ein Verweistyp ist, leitet der Compiler immer einen Nullwerte zulassenden Verweistyp ab, auch wenn der Typ eines Initialisierungsausdrucks keine Nullwerte zulässt.

var wird häufig zusammen mit einem Ausdruck mit einem Konstruktoraufruf verwendet. Die Verwendung ermöglicht var es Ihnen, einen Typnamen in einer Variablendeklaration und Objektinstanziierung zu vermeiden, wie das folgende Beispiel zeigt:

var xs = new List<int>();

Sie können als Alternative einen als Ziel typisierten new-Ausdruck verwenden:

List<int> xs = new();
List<int>? ys = new();

Wenn Sie mit anonymen Typen arbeiten, müssen Sie implizit eingegebene lokale Variablen verwenden. Das folgende Beispiel zeigt einen Abfrageausdruck, der einen anonymen Typ verwendet, um den Namen und die Telefonnummer von Kund*innen zu speichern:

var fromPhoenix = from cust in customers
                  where cust.City == "Phoenix"
                  select new { cust.Name, cust.Phone };

foreach (var customer in fromPhoenix)
{
    Console.WriteLine($"Name={customer.Name}, Phone={customer.Phone}");
}

Im vorherigen Beispiel können Sie den Typ der Variable fromPhoenix nicht explizit angeben. Der Typ ist IEnumerable<T>, aber in diesem Fall ist T ein anonymer Typ, dessen Namen Sie nicht angeben können. Aus diesem Grund müssen Sie var verwenden. Aus demselben Grund müssen Sie var verwenden, wenn Sie die Iterationsvariable customer in der foreach-Anweisung deklarieren.

Weitere Informationen zu implizit typierten lokalen Variablen finden Sie unter Implizit typierten lokalen Variablen.

Bei einem Musterabgleich wird das var-Schlüsselwort in einem var-Muster verwendet.

Verweisvariablen

Wenn Sie eine lokale Variable deklarieren und das ref-Schlüsselwort vor dem Typ der Variablen hinzufügen, deklarieren Sie eine Verweisvariable oder eine „ref local“:

ref int aliasOfvariable = ref variable;

Eine Verweisvariable ist eine Variable, die auf eine andere Variable verweist, die als Referent bezeichnet wird. Das heißt, eine Verweisvariable ist ein Alias für ihren Referenten. Wenn Sie einer Referenzvariablen einen Wert zuweisen, weisen Sie diesen Wert dem Referent zu. Wenn Sie den Wert einer Referenzvariable lesen, geben Sie den Wert des Referents zurück. Das folgende Beispiel veranschaulicht dieses Verhalten:

int a = 1;
ref int aliasOfa = ref a;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})");  // output: (a, aliasOfa) is (1, 1)

a = 2;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})");  // output: (a, aliasOfa) is (2, 2)

aliasOfa = 3;
Console.WriteLine($"(a, aliasOfa) is ({a}, {aliasOfa})");  // output: (a, aliasOfa) is (3, 3)

Verwenden Sie den ref-Zuweisungsoperator= ref, um den Referenten einer Verweisvariablen zu ändern, wie das folgende Beispiel zeigt:

void Display(int[] s) => Console.WriteLine(string.Join(" ", s));

int[] xs = [0, 0, 0];
Display(xs);

ref int element = ref xs[0];
element = 1;
Display(xs);

element = ref xs[^1];
element = 3;
Display(xs);
// Output:
// 0 0 0
// 1 0 0
// 1 0 3

Im vorstehenden Beispiel wird die element-Verweisvariable als Alias für das erste Arrayelement initialisiert. Anschließend wird ihr ref erneut zugewiesen, um auf das letzte Arrayelement zu verweisen.

Sie können eine lokale ref readonly-Variable definieren. Sie können einer ref readonly-Variablen keinen Wert zuweisen. Sie können ref eine solche Verweisvariable jedoch neu zuweisen, wie im folgenden Beispiel gezeigt:

int[] xs = [1, 2, 3];

ref readonly int element = ref xs[0];
// element = 100;  error CS0131: The left-hand side of an assignment must be a variable, property or indexer
Console.WriteLine(element);  // output: 1

element = ref xs[^1];
Console.WriteLine(element);  // output: 3

Sie können einer Verweisvariablen eine Verweisrückgabe zuweisen, wie das folgende Beispiel zeigt:

using System;

public class NumberStore
{
    private readonly int[] numbers = [1, 30, 7, 1557, 381, 63, 1027, 2550, 511, 1023];

    public ref int GetReferenceToMax()
    {
        ref int max = ref numbers[0];
        for (int i = 1; i < numbers.Length; i++)
        {
            if (numbers[i] > max)
            {
                max = ref numbers[i];
            }
        }
        return ref max;
    }

    public override string ToString() => string.Join(" ", numbers);
}

public static class ReferenceReturnExample
{
    public static void Run()
    {
        var store = new NumberStore();
        Console.WriteLine($"Original sequence: {store.ToString()}");
        
        ref int max = ref store.GetReferenceToMax();
        max = 0;
        Console.WriteLine($"Updated sequence:  {store.ToString()}");
        // Output:
        // Original sequence: 1 30 7 1557 381 63 1027 2550 511 1023
        // Updated sequence:  1 30 7 1557 381 63 1027 0 511 1023
    }
}

Im vorherigen Beispiel ist die GetReferenceToMax-Methode eine returns-by-ref-Methode. Sie gibt nicht den maximalen Wert selbst zurück, sondern eine Verweisrückgabe, die ein Alias für das Arrayelement ist, das den maximalen Wert enthält. Die Run-Methode weist der max-Verweisvariablen eine Verweisrückgabe zu. Durch Zuweisen zu max aktualisiert sie dann den internen Speicher der store-Instanz. Sie können auch eine ref readonly-Methode definieren. Die Aufrufer einer ref readonly-Methode können ihrer Verweisrückgabe keinen Wert zuweisen.

Die Iterationsvariable der foreach-Anweisung kann eine Verweisvariable sein. Weitere Informationen finden Sie im Abschnitt foreach-Anweisung im Artikel Iterationsanweisungen.

In leistungskritischen Szenarien kann die Verwendung von Verweisvariablen und Rückgaben die Leistung steigern, indem potenziell teure Kopiervorgänge vermieden werden.

Der Compiler stellt sicher, dass eine Verweisvariable ihren Referenten nicht überdauert und für die gesamte Lebensdauer gültig bleibt. Weitere Informationen finden Sie im Abschnitt Ref-safe-Kontexte der C#-Sprachspezifikation.

Informationen zu den ref-Feldern finden Sie im Abschnitt ref-Felder des Artikels ref-Strukturtypen.

Bereichsbezogene „ref“-Variable

Das kontextbezogene Schlüsselwort scoped schränkt die Lebensdauer eines Werts ein. Der Modifizierer scoped beschränkt die ref-safe-to-escape- bzw safe-to-escape-Lebensdauer auf die aktuelle Methode. Durch Hinzufügen des scoped Modifizierers bestätigen Sie, dass der Code die Lebensdauer der Variablen nicht verlängert.

Wenden Sie sich auf scoped einen Parameter oder eine lokale Variable an. Sie können den scoped Modifizierer auf Parameter und Lokale anwenden, wenn der Typ ein ref structist. Wenden Sie andernfalls den scoped Modifizierer nur auf lokale Referenzvariablen an. Diese Regel enthält lokale Variablen, die mit dem Modifizierer und den ref Parametern deklariert sind, die mit den inModifizierern refoder out Modifizierern deklariert sind.

Der scoped-Modifizierer wird implizit zu this in Methoden hinzugefügt, die in einem struct- bzw. out-Parameter und einem ref-Parameter deklariert sind, wenn der Typ ein ref struct ist.

C#-Sprachspezifikation

Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation:

Weitere Informationen zum Modifizierer scoped finden Sie im Vorschlag zu Strukturverbesserungen auf niedriger Ebene.

Weitere Informationen