Jump deyimleri - break, continue, returnve goto

Denetimi koşulsuz olarak aktaran dört C# deyimi. deyimibreak, en yakın kapsayan yineleme deyimini veya switchdeyimini 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 refreturn 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, whileveya 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 , forforeach, whileveya 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ü voidolamaz.

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 nullolamaz. Başv dönüşlü bir yöntem, değeri şu anda null (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 structyöntemi class 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ı pbir 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:

Ayrıca bkz.