Özel durum işleme deyimleri - throw, try-catch, try-finallyve try-catch-finally

özel durumlarla çalışmak için ve try deyimlerini kullanırsınızthrow. Özel durum atmak için deyimini throw kullanın. Bir kod bloğunun try yürütülmesi sırasında oluşabilecek özel durumları yakalamak ve işlemek için deyimini kullanın.

Deyimi throw

deyimi throw bir özel durum oluşturur:

if (shapeAmount <= 0)
{
    throw new ArgumentOutOfRangeException(nameof(shapeAmount), "Amount of shapes must be positive.");
}

Deyiminde throw e; , ifadenin e sonucu örtük olarak olarak olarak System.Exceptiondönüştürülebilir olmalıdır.

Örneğin, ArgumentOutOfRangeExceptionInvalidOperationExceptionveya yerleşik özel durum sınıflarını kullanabilirsiniz. .NET ayrıca belirli koşullarda özel durumlar atmak için yardımcı yöntemler sağlar: ArgumentNullException.ThrowIfNull ve ArgumentException.ThrowIfNullOrEmpty. 'den System.Exceptiontüretilen kendi özel durum sınıflarınızı da tanımlayabilirsiniz. Daha fazla bilgi için bkz . Özel durumlar oluşturma ve oluşturma.

Bir catch bloğun içinde, bloğu tarafından catch işlenen özel durumu yeniden oluşturmak için deyimini throw; kullanabilirsiniz:

try
{
    ProcessShapes(shapeAmount);
}
catch (Exception e)
{
    LogError(e, "Shape processing failed.");
    throw;
}

Not

throw; özelliğinde depolanan özel durumun özgün yığın izlemesini Exception.StackTrace korur. Bunun tersi, throw e; özelliğini egüncelleştirirStackTrace.

Özel durum oluşturulduğunda, ortak dil çalışma zamanı (CLR) bu özel durumu işleyebilen bloğu ararcatch. Şu anda yürütülen yöntem böyle bir catch blok içermiyorsa, CLR geçerli yöntemi çağıran yönteme bakar ve çağrı yığınını yukarı doğru kullanır. Blok catch bulunmazsa, CLR yürütülen iş parçacığını sonlandırır. Daha fazla bilgi için C# dil belirtiminin Özel durumlar nasıl işlenir bölümüne bakın.

İfade throw

İfade olarak da kullanabilirsiniz throw . Bu, aşağıdakileri içeren birkaç durumda kullanışlı olabilir:

  • koşullu işleç. Aşağıdaki örnek, geçirilen dizi args boş olduğunda oluşturmak için bir throwArgumentException ifade kullanır:

    string first = args.Length >= 1 
        ? args[0]
        : throw new ArgumentException("Please supply at least one argument.");
    
  • null-coalescing işleci. Aşağıdaki örnek, bir throw özelliğe atanacak dize olduğunda nulloluşturmak için bir ifade ArgumentNullException kullanır:

    public string Name
    {
        get => name;
        set => name = value ??
            throw new ArgumentNullException(paramName: nameof(value), message: "Name cannot be null");
    }
    
  • ifade gövdeli lambda veya yöntem. Aşağıdaki örnek, bir throw değere InvalidCastException dönüştürmenin desteklenmediğini belirtmek üzere oluşturmak için bir DateTime ifade kullanır:

    DateTime ToDateTime(IFormatProvider provider) =>
             throw new InvalidCastException("Conversion to a DateTime is not supported.");
    

Deyimi try

deyimini try aşağıdaki formlardan herhangi birinde kullanabilirsiniz: try-catch - bir try bloğun içindeki kodun yürütülmesi sırasında oluşabilecek özel durumları işlemek için, try-finally denetim bloktan ayrıldığında try yürütülen kodu belirtmek için ve try-catch-finally - önceki iki formun bir bileşimi olarak.

Deyimi try-catch

Kod bloğunun try-catch yürütülmesi sırasında oluşabilecek özel durumları işlemek için deyimini kullanın. Kodu bir bloğun içinde özel durumun oluşabileceği yere try yerleştirin. karşılık gelen catch blokta işlemek istediğiniz temel özel durum türünü belirtmek için catch yan tümcesi kullanın:

try
{
    var result = Process(-3, 4);
    Console.WriteLine($"Processing succeeded: {result}");
}
catch (ArgumentException e)
{
    Console.WriteLine($"Processing failed: {e.Message}");
}

Birkaç catch yan tümcesi sağlayabilirsiniz:

try
{
    var result = await ProcessAsync(-3, 4, cancellationToken);
    Console.WriteLine($"Processing succeeded: {result}");
}
catch (ArgumentException e)
{
    Console.WriteLine($"Processing failed: {e.Message}");
}
catch (OperationCanceledException)
{
    Console.WriteLine("Processing is cancelled.");
}

Bir özel durum oluştuğunda, catch yan tümceleri yukarıdan aşağıya doğru belirtilen sırada incelenir. En fazla, oluşan özel durumlar için yalnızca bir catch blok yürütülür. Yukarıdaki örnekte de gösterildiği gibi, bir özel durum değişkeninin bildirimini atlayabilir ve catch yan tümcesinde yalnızca özel durum türünü belirtebilirsiniz. Belirtilen özel durum türü olmayan catch yan tümcesi herhangi bir özel durumla eşleşir ve varsa son catch yan tümcesi olmalıdır.

Yakalanan bir özel durumu yeniden oluşturmak istiyorsanız, aşağıdaki örnekte gösterildiği gibi deyimini throwkullanın:

try
{
    var result = Process(-3, 4);
    Console.WriteLine($"Processing succeeded: {result}");
}
catch (Exception e)
{
    LogError(e, "Processing failed.");
    throw;
}

Not

throw; özelliğinde depolanan özel durumun özgün yığın izlemesini Exception.StackTrace korur. Bunun tersi, throw e; özelliğini egüncelleştirirStackTrace.

Özel when durum filtresi

Özel durum türüyle birlikte, bir özel durumu daha ayrıntılı olarak inceleyen ve ilgili catch bloğun bu özel durumu işleyip işlemeyeceğine karar veren bir özel durum filtresi de belirtebilirsiniz. Özel durum filtresi, aşağıdaki örnekte gösterildiği gibi anahtar sözcüğü izleyen when bir Boole ifadesidir:

try
{
    var result = Process(-3, 4);
    Console.WriteLine($"Processing succeeded: {result}");
}
catch (Exception e) when (e is ArgumentException || e is DivideByZeroException)
{
    Console.WriteLine($"Processing failed: {e.Message}");
}

Yukarıdaki örnek, belirtilen iki türün özel durumlarını işlemek için tek catch bir blok sağlamak için bir özel durum filtresi kullanır.

Özel durum filtreleriyle ayırt edilirlerse aynı özel durum türü için birkaç catch yan tümce sağlayabilirsiniz. Bu yan tümcelerden birinde özel durum filtresi olmayabilir. Böyle bir yan tümce varsa, bu özel durum türünü belirten yan tümcelerin sonuncusu olmalıdır.

Yan catch tümcesinde özel durum filtresi varsa, bundan sonra görüntülenen bir yan tümcenin özel durum türüyle aynı veya daha az türetilmiş özel durum türünü catch belirtebilir. Örneğin, bir özel durum filtresi varsa, yan catch (Exception e) tümcesinin son yan tümcesi olması gerekmez.

Zaman uyumsuz ve yineleyici yöntemlerindeki özel durumlar

Zaman uyumsuz bir işlevde özel durum oluşursa, aşağıdaki örnekte gösterildiği gibi işlevin sonucunu beklediğinizde işlevi çağırana yayılır:

public static async Task Run()
{
    try
    {
        Task<int> processing = ProcessAsync(-1);
        Console.WriteLine("Launched processing.");

        int result = await processing;
        Console.WriteLine($"Result: {result}.");
    }
    catch (ArgumentException e)
    {
        Console.WriteLine($"Processing failed: {e.Message}");
    }
    // Output:
    // Launched processing.
    // Processing failed: Input must be non-negative. (Parameter 'input')
}

private static async Task<int> ProcessAsync(int input)
{
    if (input < 0)
    {
        throw new ArgumentOutOfRangeException(nameof(input), "Input must be non-negative.");
    }

    await Task.Delay(500);
    return input;
}

Yineleyici yönteminde bir özel durum oluşursa, yalnızca yineleyici sonraki öğeye ilerlediğinde çağırana yayılır.

Deyimi try-finally

Deyiminde try-finallyfinally , denetim bloğu terk try ettiğinde blok yürütülür. Denetim, bunun sonucunda blokta try kalabilir

  • normal yürütme,
  • atlama deyiminin yürütülmesi (, return, break, continueveya ) veya goto
  • bir özel durumun bloğun dışına yayılması try .

Aşağıdaki örnek, denetimin finally yöntemden ayrılmadan önce bir nesnenin durumunu sıfırlamak için bloğunu kullanır:

public async Task HandleRequest(int itemId, CancellationToken ct)
{
    Busy = true;

    try
    {
        await ProcessAsync(itemId, ct);
    }
    finally
    {
        Busy = false;
    }
}

Blokta finally kullanılan ayrılmış kaynakları temizlemek için bloğunu try da kullanabilirsiniz.

Not

Bir kaynağın türü veya arabirimini uyguladığında IDisposable deyimini usinggöz önünde bulundurun.IAsyncDisposable deyimi, using denetim deyiminden ayrıldığında using alınan kaynakların atılmasını sağlar. Derleyici bir using deyimini deyimine try-finally dönüştürür.

Neredeyse tüm durumlarda finally bloklar yürütülür. Blokların yürütülmemesi yalnızca finally programın hemen sonlandırılmasını içerir. Örneğin, böyle bir sonlandırma, çağrı veya bir OverflowException veya InvalidProgramException özel durum nedeniyle Environment.FailFast oluşabilir. çoğu işletim sistemi, işlemi durdurma ve kaldırma işleminin bir parçası olarak makul bir kaynak temizleme işlemi gerçekleştirir.

Deyimi try-catch-finally

Hem bloğun yürütülmesi try sırasında oluşabilecek özel durumları işlemek hem de denetim deyiminden ayrıldığında try yürütülmesi gereken kodu belirtmek için bir try-catch-finally deyim kullanırsınız:

public async Task ProcessRequest(int itemId, CancellationToken ct)
{
    Busy = true;

    try
    {
        await ProcessAsync(itemId, ct);
    }
    catch (Exception e) when (e is not OperationCanceledException)
    {
        LogError(e, $"Failed to process request for item ID {itemId}.");
        throw;
    }
    finally
    {
        Busy = false;
    }

}

Bir özel durum bir catch blok tarafından işlendiğinde, bloğun finally yürütülmesinden sonra (bloğun catch yürütülmesi catch sırasında başka bir özel durum gerçekleşse bile) blok yürütülür. ve blokları hakkında catch bilgi için sırasıyla Deyimitry-catch ve Deyimi try-finally bölümlerine bakın.finally

C# dili belirtimi

Daha fazla bilgi için C# dil belirtiminin aşağıdaki bölümlerine bakın:

Ayrıca bkz.