Özel durum işleme deyimleri - throw
, try-catch
, try-finally
ve 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, ArgumentOutOfRangeException InvalidOperationExceptionveya yerleşik özel durum sınıflarını kullanabilirsiniz. .NET ayrıca belirli koşullarda özel durumlar atmak için aşağıdaki yardımcı yöntemleri de 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 e
gü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 birthrow
ArgumentException 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ğundanull
oluş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 throw
kullanı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 e
gü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-finally
finally
, 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
,continue
veya ) veyagoto
- 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 using
gö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.
Bloğun finally
yürütülmesi, işletim sisteminin bir özel durum geri alma işlemini tetikleyip tetiklemediğine bağlıdı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 Deyimi try-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: