Jump deyimleri - break
, continue
, return
ve goto
Denetimi koşulsuz olarak aktaran dört C# deyimi. deyimibreak
, en yakın kapsayan yineleme deyimini veya switch
deyimini sonlandırır. deyimi, continue
en yakın kapsayan yineleme deyiminin yeni bir yinelemesini başlatır. deyimireturn
: göründüğü işlevin yürütülmesini sonlandırır ve denetimi çağırana döndürür. Bir ref
return
deyimdeki değiştirici, döndürülen ifadenin değere göre değil başvuru tarafından döndürülür olduğunu gösterir. deyimigoto
: denetimi bir etiketle işaretlenmiş bir deyime aktarır.
Özel durum oluşturan ve koşulsuz olarak denetimi de aktaran deyimi hakkında throw
bilgi için bkz. throw.
deyimi break
deyimi, break
en yakın kapsayan yineleme deyimini (yani, for
, foreach
, while
veya do
döngüsü) veya switch
deyimini sonlandırır. deyimi, break
varsa, denetimi sonlandırılan deyimini izleyen deyime aktarır.
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.
İç içe döngülerde deyimi, break
aşağıdaki örnekte gösterildiği gibi yalnızca onu içeren en içteki döngüyü sonlandırır:
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
deyimini switch
bir döngü içinde kullandığınızda, break
switch bölümünün sonundaki bir deyim denetimi yalnızca deyimin switch
dışına aktarır. Aşağıdaki örnekte gösterildiği gibi deyimini switch
içeren döngü etkilenmez:
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.
deyimi continue
deyimi, continue
aşağıdaki örnekte gösterildiği gibi en yakın kapsayan yineleme deyiminin (yani , for
foreach
, while
veya do
döngüsü) yeni bir yinelemesini başlatır:
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
deyimi return
deyimi, return
göründüğü işlevin yürütülmesini sonlandırır ve denetimi ve varsa işlevin sonucunu çağırana döndürür.
İşlev üyesi bir değeri hesaplamazsa, aşağıdaki örnekte gösterildiği gibi deyimini ifade olmadan kullanırsınız return
:
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
Yukarıdaki örnekte gösterildiği gibi, genellikle bir işlev üyesini return
erken sonlandırmak için ifade olmadan deyimini kullanırsınız. İşlev üyesi deyimini return
içermiyorsa, son deyimi yürütüldükten sonra sonlandırılır.
Bir işlev üyesi bir değeri hesaplarsa, aşağıdaki örnekte gösterildiği gibi deyimini bir ifadeyle kullanırsınız return
:
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;
}
deyimi bir ifadeye return
sahip olduğunda, bu ifade zaman uyumsuz olmadığı sürece bir işlev üyesinin dönüş türüne örtük olarak dönüştürülebilir olmalıdır. Bir async
işlevden döndürülen ifade, işlevin dönüş türünden hangisiyse, veya ValueTask<TResult>türü bağımsız değişkenine Task<TResult> örtük olarak dönüştürülebilir olmalıdır. bir async
işlevin dönüş türü veya ValueTaskise Task deyimini return
ifade olmadan kullanırsınız.
Varsayılan olarak, return
deyimi bir ifadenin değerini döndürür. Bir değişkene başvuru döndürebilirsiniz. Bunu yapmak için aşağıdaki örnekte gösterildiği gibi deyiminiref
anahtar sözcüğüyle birlikte kullanınreturn
:
var 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.");
}
Başvuru dönüşleri
Dönüş değerleri başvuru (ref
dönüşler) ile döndürülebilir. Başvuru dönüş değeri, bir yöntemin çağırana değer yerine bir değişkene başvuru döndürmesine olanak tanır. Çağıran daha sonra döndürülen değişkeni değer veya başvuru tarafından döndürüldü gibi ele almayı seçebilir. Çağıran, döndürülen değere başvuru olan ve başv yerel olarak adlandırılan yeni bir değişken oluşturabilir. Başvuru dönüş değeri, yöntemin bir değişkene başvuru (veya diğer ad) döndürdüğü anlamına gelir. Bu değişkenin kapsamı yöntemini içermelidir. Bu değişkenin yaşam süresi yöntemin dönüşünün ötesine geçmelidir. Çağıran tarafından yöntemin dönüş değerinde yapılan değişiklikler, yöntemi tarafından döndürülen değişkende yapılır.
Bir yöntemin başvuru dönüş değeri döndürdüğünü bildirmek, yöntemin bir değişkene diğer ad döndürdüğünü gösterir. Tasarım amacı genellikle kodu çağırmanın diğer ad aracılığıyla bu değişkene erişmesi ve bunu değiştirmek de dahil olmak üzere olmasıdır. Başvuruyla döndürülen yöntemlerin dönüş türü void
olamaz.
ref
Dönüş değeri, çağrılan yöntemin kapsamındaki başka bir değişkenin diğer adıdır. Başvuru dönüşünün herhangi bir kullanımını diğer ad olarak değişkenini kullanarak yorumlayabilirsiniz:
- Değerini atadığınızda, değişkenine diğer ad olarak bir değer atarsınız.
- Değerini okuduğunuzda, diğer adlarına sahip olduğu değişkenin değerini okursunuz.
- Başvuruya göre döndürürseniz, aynı değişkene bir diğer ad döndürebilirsiniz.
- Başvuru yoluyla başka bir yönteme geçirirseniz, diğer ad olarak kullandığı değişkene bir başvuru geçirirsiniz.
- Bir başvuru yerel diğer adı yaptığınızda, aynı değişken için yeni bir diğer ad oluşturursunuz.
Başvuru dönüşünü çağırma yöntemine ref_safe_to_escape gerekir. Bu, şu anlama gelir:
- Dönüş değeri, yönteminin yürütülmesinin ötesine uzanan bir yaşam süresine sahip olmalıdır. Başka bir deyişle, bunu döndüren yönteminde yerel bir değişken olamaz. Bir sınıfın örneği veya statik alanı olabileceği gibi yöntemine geçirilen bir bağımsız değişken de olabilir. Yerel bir değişken döndürülmeye çalışılması, "Başvuruyla yerel 'obj' döndürülemiyor çünkü başvuru yerel bir başvuru değil" derleyici hatası CS8168 oluşturur.
- Dönüş değeri değişmez değer
null
olamaz. Başv dönüşlü bir yöntem, değeri şu andanull
(doğrulanmamış) değer veya değer türü için null atanabilir değer türü olan bir değişkene diğer ad döndürebilir. - Dönüş değeri sabit, numaralandırma üyesi, bir özellikten değere göre dönüş değeri veya veya
struct
yöntemiclass
olamaz.
Ayrıca, zaman uyumsuz yöntemlerde başvuru dönüş değerlerine izin verilmez. Zaman uyumsuz bir yöntem yürütmeyi tamamlamadan önce döndürebilir, ancak dönüş değeri hala bilinmemektedir.
Başvuru dönüş değeri döndüren bir yöntem:
- dönüş türünün önüne ref anahtar sözcüğünü ekleyin.
- Yöntem gövdesindeki her return deyimi, döndürülen örneğin adının önünde ref anahtar sözcüğünü içerir.
Aşağıdaki örnekte, bu koşulları karşılayan ve adlı p
bir nesneye başvuru döndüren bir Person
yöntem gösterilmektedir:
public ref Person GetContactInformation(string fname, string lname)
{
// ...method implementation...
return ref p;
}
deyimi goto
Deyimi goto
, aşağıdaki örnekte gösterildiği gibi denetimi bir etiketle işaretlenmiş bir deyime aktarır:
var matrices = new Dictionary<string, int[][]>
{
["A"] = new[]
{
new[] { 1, 2, 3, 4 },
new[] { 4, 3, 2, 1 }
},
["B"] = new[]
{
new[] { 5, 6, 7, 8 },
new[] { 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.
Yukarıdaki örnekte gösterildiği gibi, iç içe döngüden çıkmak için deyimini goto
kullanabilirsiniz.
İpucu
İç içe döngülerle çalışırken, ayrı döngüleri ayrı yöntemler halinde yeniden düzenlemeyi göz önünde bulundurun. Bu, deyimi olmadan daha basit ve daha okunabilir bir koda goto
yol açabilir.
Aşağıdaki örnekte gösterildiği gibi, denetimi sabit bir büyük/küçük harf etiketine sahip bir switch bölümüne aktarmak için deyimindeki deyimini switch
de kullanabilirsinizgoto
:
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;
}
}
deyiminde switch
, denetimi etiketli switch bölümüne aktarmak için deyimini goto default;
default
de kullanabilirsiniz.
Verilen ada sahip bir etiket geçerli işlev üyesinde yoksa veya deyimi etiket kapsamında değilse goto
, derleme zamanı hatası oluşur. Yani, denetimi geçerli işlev üyesinin dışına veya herhangi bir iç içe geçmiş kapsama (örneğin, bir try
blok) aktarmak için deyimini kullanamazsınızgoto
.
C# dili belirtimi
Daha fazla bilgi için C# dil belirtiminin aşağıdaki bölümlerine bakın: