Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Pernyataan lompat -
Pernyataan lompat mentransfer kontrol tanpa syarat. Pernyataan mengakhiri break pernyataan atau switch pernyataaniterasi yang menutupi terdekat. Pernyataan memulai continue iterasi baru dari pernyataan iterasi penutup terdekat.
Pernyataanreturn mengakhiri eksekusi fungsi di mana ia muncul dan mengembalikan kontrol ke pemanggil. Pernyataan mentransfer goto kontrol ke pernyataan yang ditandai oleh label.
Untuk informasi tentang throw pernyataan yang melempar pengecualian dan kontrol transfer tanpa syarat juga, lihat throw bagian pernyataan dari artikel Pernyataan penanganan pengecualian.
Pernyataan break
Pernyataan mengakhiri breakpernyataan iterasi penutup terdekat (yaitu, , for, foreachwhile, atau do perulangan) atau switch pernyataan. Pernyataan tersebut break mentransfer kontrol ke pernyataan yang mengikuti pernyataan yang dihentikan, jika ada.
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.
Dalam perulangan berlapis, break pernyataan hanya mengakhiri perulangan terdalu yang berisinya, seperti yang ditunjukkan contoh berikut:
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
Saat Anda menggunakan switch pernyataan di dalam perulangan, break pernyataan di akhir bagian pengalihan mentransfer kontrol hanya di switch luar pernyataan. Perulangan yang berisi switch pernyataan tidak terpengaruh, seperti yang ditunjukkan contoh berikut:
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.
Pernyataan continue
Pernyataan memulai continue iterasi baru dari pernyataan iterasi penutup terdekat (yaitu, , for, foreachwhile, atau do perulangan), seperti yang ditunjukkan contoh berikut:
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
Pernyataan return
Pernyataan return mengakhiri eksekusi fungsi tempat fungsi muncul dan mengembalikan kontrol dan hasil fungsi, jika ada, kepada pemanggil.
Jika anggota fungsi tidak menghitung nilai, Anda menggunakan return pernyataan tanpa ekspresi, seperti yang ditunjukkan contoh berikut:
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
Seperti yang ditunjukkan oleh contoh sebelumnya, Anda biasanya menggunakan return pernyataan tanpa ekspresi untuk mengakhiri anggota fungsi lebih awal. Jika anggota fungsi tidak berisi return pernyataan, pernyataan akan dihentikan setelah pernyataan terakhir dijalankan.
Jika anggota fungsi menghitung nilai, Anda menggunakan return pernyataan dengan ekspresi, seperti yang ditunjukkan contoh berikut:
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;
}
return Ketika pernyataan memiliki ekspresi, ekspresi tersebut harus secara implisit dapat dikonversi ke jenis pengembalian anggota fungsi kecuali jika asinkron. Ekspresi yang async dikembalikan dari fungsi harus secara implisit dapat dikonversi ke argumen Task<TResult> jenis atau ValueTask<TResult>, mana pun yang merupakan jenis pengembalian fungsi. Jika jenis async pengembalian fungsi adalah Task atau ValueTask, Anda menggunakan return pernyataan tanpa ekspresi.
Ref mengembalikan
Secara default, return pernyataan mengembalikan nilai ekspresi. Anda dapat mengembalikan referensi ke variabel. Nilai pengembalian referensi (atau pengembalian ref) adalah nilai yang dikembalikan oleh metode berdasarkan referensi ke pemanggil. Artinya, pemanggil dapat memodifikasi nilai yang dikembalikan oleh metode, dan perubahan tersebut tercermin dalam status objek dalam metode yang disebut. Untuk melakukannya, gunakan return pernyataan dengan ref kata kunci, seperti yang ditunjukkan contoh berikut:
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.");
}
Nilai pengembalian referensi memungkinkan metode untuk mengembalikan referensi ke variabel, bukan nilai, kembali ke pemanggil. Pemanggil kemudian dapat memilih untuk memperlakukan variabel yang dikembalikan seolah-olah dikembalikan oleh nilai atau berdasarkan referensi. Pemanggil dapat membuat variabel baru yang merupakan referensi ke nilai yang dikembalikan, yang disebut lokal ref. Nilai pengembalian referensi berarti bahwa metode mengembalikan referensi (atau alias) ke beberapa variabel. Cakupan variabel tersebut harus menyertakan metode . Masa pakai variabel tersebut harus melampaui pengembalian metode. Modifikasi pada nilai pengembalian metode oleh pemanggil dibuat ke variabel yang dikembalikan oleh metode .
Menyatakan bahwa metode mengembalikan nilai pengembalian referensi menunjukkan bahwa metode mengembalikan alias ke variabel. Niat desain sering kali memanggil kode mengakses variabel tersebut melalui alias, termasuk untuk memodifikasinya. Metode yang dikembalikan berdasarkan referensi tidak boleh memiliki jenis voidpengembalian .
Agar pemanggil mengubah status objek, nilai pengembalian referensi harus disimpan ke variabel yang secara eksplisit didefinisikan sebagai variabel referensi.
Nilai ref yang dikembalikan adalah alias ke variabel lain dalam cakupan metode yang disebut. Anda dapat menginterpretasikan penggunaan pengembalian ref seperti menggunakan variabel aliasnya:
- Saat Menetapkan nilainya, Anda menetapkan nilai ke variabel aliasnya.
- Saat Anda membaca nilainya, Anda membaca nilai variabel aliasnya.
- Jika Anda mengembalikannya dengan referensi, Anda mengembalikan alias ke variabel yang sama.
- Jika Anda meneruskannya ke metode lain dengan referensi, Anda meneruskan referensi ke variabel aliasnya.
- Ketika Anda membuat alias lokal ref , Anda membuat alias baru ke variabel yang sama.
Pengembalian ref harus berupa ref-safe-context ke metode panggilan. Itu berarti:
- Nilai pengembalian harus memiliki masa pakai yang meluas di luar eksekusi metode . Dengan kata lain, itu tidak boleh menjadi variabel lokal dalam metode yang mengembalikannya. Ini bisa berupa instans atau bidang statis kelas, atau dapat berupa argumen yang diteruskan ke metode . Mencoba mengembalikan variabel lokal menghasilkan kesalahan kompilator CS8168, "Tidak dapat mengembalikan 'obj' lokal dengan referensi karena bukan lokal ref."
- Nilai yang dikembalikan tidak boleh berupa literal
null. Metode dengan pengembalian ref dapat mengembalikan alias ke variabel yang nilainya saat ininulladalah nilai (tidak terinstansiasi) atau jenis nilai nullable untuk jenis nilai. - Nilai yang dikembalikan tidak boleh berupa konstanta, anggota enumerasi, nilai pengembalian menurut nilai dari properti, atau metode atau
classstruct.
Selain itu, nilai pengembalian referensi tidak diizinkan pada metode asinkron. Metode asinkron dapat kembali sebelum selesai dieksekusi, sementara nilai pengembaliannya masih belum diketahui.
Metode yang mengembalikan nilai pengembalian referensi harus:
- Sertakan kata kunci ref di depan jenis pengembalian.
- Setiap pernyataan pengembalian dalam isi metode menyertakan kata kunci ref di depan nama instans yang dikembalikan.
Contoh berikut menunjukkan metode yang memenuhi kondisi tersebut dan mengembalikan referensi ke Person objek bernama p:
public ref Person GetContactInformation(string fname, string lname)
{
// ...method implementation...
return ref p;
}
Berikut adalah contoh pengembalian ref yang lebih lengkap, memperlihatkan tanda tangan metode dan isi metode.
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");
}
Metode yang dipanggil juga dapat mendeklarasikan nilai ref readonly pengembalian untuk mengembalikan nilai menurut referensi, dan memberlakukan bahwa kode panggilan tidak dapat mengubah nilai yang dikembalikan. Metode panggilan dapat menghindari penyalinan nilai yang dikembalikan dengan menyimpan nilai dalam variabel referensi lokal ref readonly .
Contoh berikut mendefinisikan Book kelas yang memiliki dua String bidang, Title dan Author. Ini juga mendefinisikan BookCollection kelas yang mencakup array Book objek privat. Objek buku individual dikembalikan dengan referensi dengan memanggil metodenya GetBookByTitle .
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();
}
}
Ketika penelepon menyimpan nilai yang dikembalikan oleh GetBookByTitle metode sebagai lokal ref, perubahan yang dilakukan pemanggil ke nilai pengembalian tercermin dalam objek, seperti yang ditunjukkan BookCollection contoh berikut.
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
Pernyataan goto
Pernyataan mentransfer goto kontrol ke pernyataan yang ditandai oleh label, seperti yang ditunjukkan contoh berikut:
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.
Seperti yang ditunjukkan contoh sebelumnya, Anda dapat menggunakan goto pernyataan untuk keluar dari perulangan berlapis.
Tip
Saat Anda bekerja dengan perulangan berlapis, pertimbangkan untuk memfaktorkan ulang perulangan terpisah ke dalam metode terpisah. Itu dapat menyebabkan kode yang lebih sederhana dan lebih mudah dibaca tanpa goto pernyataan.
Anda juga dapat menggunakan goto pernyataan dalam switch pernyataan untuk mentransfer kontrol ke bagian pengalihan dengan label kasus konstanta, seperti yang ditunjukkan contoh berikut:
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;
}
}
switch Dalam pernyataan, Anda juga dapat menggunakan pernyataan goto default; untuk mentransfer kontrol ke bagian pengalihan dengan default label.
Jika label dengan nama yang diberikan tidak ada di anggota fungsi saat ini, atau jika goto pernyataan tidak berada dalam lingkup label, kesalahan waktu kompilasi terjadi. Artinya, Anda tidak dapat menggunakan goto pernyataan untuk mentransfer kontrol keluar dari anggota fungsi saat ini atau ke dalam cakupan berlapis apa pun.
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat bagian berikut dari spesifikasi bahasa C#: