Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Jump-Anweisungen -
Die Sprunganweisungen übertragen bedingungslos die Steuerung. Die break Anweisung beendet die am nächsten eingeschlossene Iterationsanweisung oder switch -anweisung. Die continue Anweisung beginnt eine neue Iteration der am nächsten eingeschlossenen Iterationsanweisung. Die return Anweisung beendet die Ausführung der Funktion, in der sie angezeigt wird, und gibt die Steuerung an den Aufrufer zurück. Die goto Anweisung überträgt die Steuerung an eine Anweisung, die durch eine Bezeichnung gekennzeichnet ist.
Informationen zu der throw Anweisung, die eine Ausnahme auslöst und die Kontrolle bedingungslos überträgt, finden Sie im throw Abschnitt "Anweisung" des Artikels "Ausnahmebehandlungsanweisungen".
Die Anweisung break
Die break Anweisung beendet die am nächsten eingeschlossene Iterationsanweisung (d. h. , for, foreach, whileoder schleifen) oder doswitch Anweisung. Die break Anweisung überträgt die Kontrolle an die Anweisung, die auf die beendete Anweisung folgt, falls vorhanden.
int[] numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
foreach (int number in numbers)
{
if (number == 3)
{
break;
}
Console.Write($"{number} ");
}
Console.WriteLine();
Console.WriteLine("End of the example.");
// Output:
// 0 1 2
// End of the example.
In geschachtelten Schleifen beendet die break Anweisung nur die innerste Schleife, die sie enthält, wie im folgenden Beispiel gezeigt:
for (int outer = 0; outer < 5; outer++)
{
for (int inner = 0; inner < 5; inner++)
{
if (inner > outer)
{
break;
}
Console.Write($"{inner} ");
}
Console.WriteLine();
}
// Output:
// 0
// 0 1
// 0 1 2
// 0 1 2 3
// 0 1 2 3 4
Wenn Sie die switch Anweisung in einer Schleife verwenden, überträgt eine break Anweisung am Ende eines Switch-Abschnitts nur die Steuerung aus der switch Anweisung. Die Schleife, die die switch Anweisung enthält, ist nicht betroffen, wie im folgenden Beispiel gezeigt:
double[] measurements = [-4, 5, 30, double.NaN];
foreach (double measurement in measurements)
{
switch (measurement)
{
case < 0.0:
Console.WriteLine($"Measured value is {measurement}; too low.");
break;
case > 15.0:
Console.WriteLine($"Measured value is {measurement}; too high.");
break;
case double.NaN:
Console.WriteLine("Failed measurement.");
break;
default:
Console.WriteLine($"Measured value is {measurement}.");
break;
}
}
// Output:
// Measured value is -4; too low.
// Measured value is 5.
// Measured value is 30; too high.
// Failed measurement.
Die Anweisung continue
Die continue Anweisung beginnt eine neue Iteration der am nächsten eingeschlossenen Iterationsanweisung (d. b. , forforeach, whileoder do Schleife), wie das folgende Beispiel zeigt:
for (int i = 0; i < 5; i++)
{
Console.Write($"Iteration {i}: ");
if (i < 3)
{
Console.WriteLine("skip");
continue;
}
Console.WriteLine("done");
}
// Output:
// Iteration 0: skip
// Iteration 1: skip
// Iteration 2: skip
// Iteration 3: done
// Iteration 4: done
Die Anweisung return
Die return Anweisung beendet die Ausführung der Funktion, in der sie angezeigt wird, und gibt die Steuerung und das Ergebnis der Funktion (falls vorhanden) an den Aufrufer zurück.
Wenn ein Funktionselement keinen Wert berechnet, verwenden Sie die return Anweisung ohne Ausdruck, wie das folgende Beispiel zeigt:
Console.WriteLine("First call:");
DisplayIfNecessary(6);
Console.WriteLine("Second call:");
DisplayIfNecessary(5);
void DisplayIfNecessary(int number)
{
if (number % 2 == 0)
{
return;
}
Console.WriteLine(number);
}
// Output:
// First call:
// Second call:
// 5
Wie im vorherigen Beispiel gezeigt, verwenden Sie in der Regel die return Anweisung ohne Ausdruck, um ein Funktionselement frühzeitig zu beenden. Wenn ein Funktionselement die return Anweisung nicht enthält, wird es nach der letzten Ausführung der Anweisung beendet.
Wenn ein Funktionselement einen Wert berechnet, verwenden Sie die return Anweisung mit einem Ausdruck, wie das folgende Beispiel zeigt:
double surfaceArea = CalculateCylinderSurfaceArea(1, 1);
Console.WriteLine($"{surfaceArea:F2}"); // output: 12.57
double CalculateCylinderSurfaceArea(double baseRadius, double height)
{
double baseArea = Math.PI * baseRadius * baseRadius;
double sideArea = 2 * Math.PI * baseRadius * height;
return 2 * baseArea + sideArea;
}
Wenn die Anweisung über einen Ausdruck verfügt, muss dieser return Ausdruck implizit in den Rückgabetyp eines Funktionsmememers wandeln, es sei denn, er ist asynchron. Der von einer async Funktion zurückgegebene Ausdruck muss implizit in das Typargument oder Task<TResult>ValueTask<TResult>, je nachdem, welcher Rückgabetyp die Funktion ist, konvertierbar sein. Wenn der Rückgabetyp einer async Funktion lautet Task oder ValueTask, verwenden Sie die return Anweisung ohne Ausdruck.
Bezugsrückkehrer
Standardmäßig gibt die return Anweisung den Wert eines Ausdrucks zurück. Sie können einen Verweis auf eine Variable zurückgeben. Referenzrücklaufwerte (oder Bezugsrückgaben) sind Werte, die von einer Methode durch Verweis auf den Aufrufer zurückgegeben werden. Das heißt, der Aufrufer kann den von einer Methode zurückgegebenen Wert ändern, und diese Änderung wird im Zustand des Objekts in der aufgerufenen Methode widergespiegelt. Verwenden Sie dazu die return Anweisung mit dem ref Schlüsselwort, wie im folgenden Beispiel gezeigt:
int[] xs = new int [] {10, 20, 30, 40 };
ref int found = ref FindFirst(xs, s => s == 30);
found = 0;
Console.WriteLine(string.Join(" ", xs)); // output: 10 20 0 40
ref int FindFirst(int[] numbers, Func<int, bool> predicate)
{
for (int i = 0; i < numbers.Length; i++)
{
if (predicate(numbers[i]))
{
return ref numbers[i];
}
}
throw new InvalidOperationException("No element satisfies the given condition.");
}
Ein Verweisrückwert ermöglicht es einer Methode, einen Verweis auf eine Variable und nicht auf einen Wert zurück an einen Aufrufer zurückzugeben. Der Aufrufer kann dann die zurückgegebene Variable so behandeln, als ob sie von Wert oder Verweis zurückgegeben wurde. Der Aufrufer kann eine neue Variable erstellen, die selbst ein Verweis auf den zurückgegebenen Wert ist, der als ref local bezeichnet wird. Ein Verweisrückwert bedeutet, dass eine Methode einen Verweis (oder einen Alias) auf eine Variable zurückgibt. Der Bereich dieser Variablen muss die Methode enthalten. Die Lebensdauer dieser Variablen muss über die Rückgabe der Methode hinausgehen. Änderungen am Rückgabewert der Methode durch den Aufrufer werden an der Variablen vorgenommen, die von der Methode zurückgegeben wird.
Das Deklarieren, dass eine Methode einen Verweisrückwert zurückgibt , gibt an, dass die Methode einen Alias für eine Variable zurückgibt. Die Entwurfsabsicht ist häufig, dass der Aufruf von Code über den Alias auf diese Variable zugreift, einschließlich des Änderns. Methoden, die nach Verweis zurückgegeben werden, können nicht über den Rückgabetyp voidverfügen.
Damit der Aufrufer den Status des Objekts ändern kann, muss der Verweisrückwert in einer Variablen gespeichert werden, die explizit als Referenzvariable definiert ist.
Der ref Rückgabewert ist ein Alias für eine andere Variable im Bereich der aufgerufenen Methode. Sie können jede Verwendung der Referenzrückgabe so interpretieren, dass sie die Variable verwendet, die sie aliase verwendet:
- Wenn Sie seinen Wert zuweisen, weisen Sie der Variablen einen Wert zu, der er aliase.
- Wenn Sie den Wert lesen, lesen Sie den Wert der Variablen, die er aliase.
- Wenn Sie ihn per Verweis zurückgeben, geben Sie einen Alias an dieselbe Variable zurück.
- Wenn Sie sie per Verweis an eine andere Methode übergeben, übergeben Sie einen Verweis auf die Variable, die sie aliase.
- Wenn Sie einen referenz lokalen Alias erstellen, erstellen Sie einen neuen Alias für dieselbe Variable.
Ein Verweisrücklauf muss ref-safe-context für die aufrufende Methode sein. Das bedeutet:
- Der Rückgabewert muss eine Lebensdauer aufweisen, die über die Ausführung der Methode hinausgeht. Mit anderen Worten, es kann keine lokale Variable in der Methode sein, die sie zurückgibt. Es kann sich um eine Instanz oder ein statisches Feld einer Klasse handeln, oder es kann sich um ein Argument handeln, das an die Methode übergeben wird. Beim Versuch, eine lokale Variable zurückzugeben, wird der Compilerfehler CS8168 generiert: "Lokale 'obj' kann nicht durch Verweis zurückgegeben werden, da es sich nicht um einen lokalen Verweis handelt."
- Der Rückgabewert kann nicht das Literal
nullsein. Eine Methode mit einer Verweisrückgabe kann einen Alias an eine Variable zurückgeben, deren Wert zurzeit dernull(unbeabsichtigte) Wert oder ein Nullwerttyp für einen Werttyp ist. - Der Rückgabewert kann keine Konstante, ein Enumerationsmememm, der Rückgabewert aus einer Eigenschaft oder eine Methode eines oder
structmehrererclassWerte sein.
Darüber hinaus sind Referenzrücklaufwerte für asynchrone Methoden nicht zulässig. Eine asynchrone Methode kann zurückgegeben werden, bevor sie die Ausführung abgeschlossen hat, während der Rückgabewert noch unbekannt ist.
Eine Methode, die einen Verweisrücklaufwert zurückgibt , muss:
- Schließen Sie das Ref-Schlüsselwort vor dem Rückgabetyp ein.
- Jede Rückgabe-Anweisung im Methodentext enthält das Ref-Schlüsselwort vor dem Namen der zurückgegebenen Instanz.
Das folgende Beispiel zeigt eine Methode, die diese Bedingungen erfüllt und einen Verweis auf ein Person Objekt mit dem Namen pzurückgibt:
public ref Person GetContactInformation(string fname, string lname)
{
// ...method implementation...
return ref p;
}
Hier ist ein vollständiges Referenzrückgabebeispiel, das sowohl die Methodensignatur als auch den Textkörper der Methode zeigt.
public static ref int Find(int[,] matrix, Func<int, bool> predicate)
{
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
if (predicate(matrix[i, j]))
return ref matrix[i, j];
throw new InvalidOperationException("Not found");
}
Die aufgerufene Methode kann auch den Rückgabewert deklarieren, um ref readonly den Wert per Verweis zurückzugeben, und erzwingen, dass der aufrufende Code den zurückgegebenen Wert nicht ändern kann. Die aufrufende Methode kann das Kopieren des zurückgegebenen Werts vermeiden, indem der Wert in einer lokalen ref readonly Referenzvariable gespeichert wird.
Das folgende Beispiel definiert eine Book Klasse mit zwei String Feldern Title und Author. Außerdem wird eine BookCollection Klasse definiert, die ein privates Array von Book Objekten enthält. Einzelne Buchobjekte werden durch Aufrufen der GetBookByTitle Methode durch Verweis zurückgegeben.
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();
}
}
Wenn der Aufrufer den von der GetBookByTitle Methode zurückgegebenen Wert als ref local speichert, werden Änderungen, die der Aufrufer an dem Rückgabewert vorgibt, im BookCollection Objekt widergespiegelt, wie im folgenden Beispiel gezeigt.
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
Die Anweisung goto
Die goto Anweisung überträgt die Steuerung an eine Anweisung, die durch eine Bezeichnung gekennzeichnet ist, wie das folgende Beispiel zeigt:
var matrices = new Dictionary<string, int[][]>
{
["A"] =
[
[1, 2, 3, 4],
[4, 3, 2, 1]
],
["B"] =
[
[5, 6, 7, 8],
[8, 7, 6, 5]
],
};
CheckMatrices(matrices, 4);
void CheckMatrices(Dictionary<string, int[][]> matrixLookup, int target)
{
foreach (var (key, matrix) in matrixLookup)
{
for (int row = 0; row < matrix.Length; row++)
{
for (int col = 0; col < matrix[row].Length; col++)
{
if (matrix[row][col] == target)
{
goto Found;
}
}
}
Console.WriteLine($"Not found {target} in matrix {key}.");
continue;
Found:
Console.WriteLine($"Found {target} in matrix {key}.");
}
}
// Output:
// Found 4 in matrix A.
// Not found 4 in matrix B.
Wie im vorherigen Beispiel gezeigt, können Sie die goto Anweisung verwenden, um aus einer geschachtelten Schleife herauszukommen.
Tipp
Wenn Sie mit geschachtelten Schleifen arbeiten, sollten Sie separate Schleifen in separate Methoden umgestalten. Dies kann zu einem einfacheren, besser lesbaren Code ohne die goto Anweisung führen.
Sie können die Anweisung in der gotoswitch Anweisung auch verwenden, um die Steuerung in einen Switch-Abschnitt mit einer konstanten Groß-/Kleinschreibungsbezeichnung zu übertragen, wie das folgende Beispiel zeigt:
using System;
public enum CoffeeChoice
{
Plain,
WithMilk,
WithIceCream,
}
public class GotoInSwitchExample
{
public static void Main()
{
Console.WriteLine(CalculatePrice(CoffeeChoice.Plain)); // output: 10.0
Console.WriteLine(CalculatePrice(CoffeeChoice.WithMilk)); // output: 15.0
Console.WriteLine(CalculatePrice(CoffeeChoice.WithIceCream)); // output: 17.0
}
private static decimal CalculatePrice(CoffeeChoice choice)
{
decimal price = 0;
switch (choice)
{
case CoffeeChoice.Plain:
price += 10.0m;
break;
case CoffeeChoice.WithMilk:
price += 5.0m;
goto case CoffeeChoice.Plain;
case CoffeeChoice.WithIceCream:
price += 7.0m;
goto case CoffeeChoice.Plain;
}
return price;
}
}
Innerhalb der switch Anweisung können Sie auch die Anweisung goto default; verwenden, um die Steuerung in den Switch-Abschnitt mit der default Bezeichnung zu übertragen.
Wenn eine Bezeichnung mit dem angegebenen Namen nicht im aktuellen Funktionselement vorhanden ist oder sich die goto Anweisung nicht im Bereich der Bezeichnung befindet, tritt ein Kompilierungszeitfehler auf. Das heißt, Sie können die goto Anweisung nicht verwenden, um die Kontrolle aus dem aktuellen Funktionselement oder in einen geschachtelten Bereich zu übertragen.
C#-Sprachspezifikation
Weitere Informationen finden Sie in den folgenden Abschnitten der C#-Sprachspezifikation: