Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makale, bu API'nin başvuru belgelerine ek açıklamalar sağlar.
Exception sınıfı, tüm özel durumlar için temel sınıftır. Bir hata oluştuğunda, sistem veya şu anda yürütülen uygulama, hata hakkında bilgi içeren bir özel durum oluşturarak bunu bildirir. Bir özel durum oluşturulduktan sonra uygulama veya varsayılan özel durum işleyicisi tarafından işlenir.
Hatalar ve özel durumlar
Çalışma zamanı hataları çeşitli nedenlerle oluşabilir. Ancak, tüm hatalar kodunuzda özel durum olarak işlenmemelidir. Çalışma zamanında oluşabilecek bazı hata kategorileri ve bunlara yanıt vermenin uygun yolları aşağıdadır.
Kullanım hataları. Kullanım hatası, program mantığındaki özel duruma neden olabilecek bir hatayı temsil eder. Ancak hata, özel durum işleme yoluyla değil, hatalı kodu değiştirerek giderilmelidir. Örneğin, aşağıdaki örnekteki Object.Equals(Object) yönteminin geçersiz kılınması,
obj
bağımsız değişkeninin her zaman null olmaması gerektiğini varsayar.using System; public class Person1 { private string _name; public string Name { get { return _name; } set { _name = value; } } public override int GetHashCode() { return this.Name.GetHashCode(); } public override bool Equals(object obj) { // This implementation contains an error in program logic: // It assumes that the obj argument is not null. Person1 p = (Person1) obj; return this.Name.Equals(p.Name); } } public class UsageErrorsEx1 { public static void Main() { Person1 p1 = new Person1(); p1.Name = "John"; Person1 p2 = null; // The following throws a NullReferenceException. Console.WriteLine($"p1 = p2: {p1.Equals(p2)}"); } }
// In F#, null is not a valid state for declared types // without 'AllowNullLiteralAttribute' [<AllowNullLiteral>] type Person() = member val Name = "" with get, set override this.GetHashCode() = this.Name.GetHashCode() override this.Equals(obj) = // This implementation contains an error in program logic: // It assumes that the obj argument is not null. let p = obj :?> Person this.Name.Equals p.Name let p1 = Person() p1.Name <- "John" let p2: Person = null // The following throws a NullReferenceException. printfn $"p1 = p2: {p1.Equals p2}"
Public Class Person Private _name As String Public Property Name As String Get Return _name End Get Set _name = value End Set End Property Public Overrides Function Equals(obj As Object) As Boolean ' This implementation contains an error in program logic: ' It assumes that the obj argument is not null. Dim p As Person = CType(obj, Person) Return Me.Name.Equals(p.Name) End Function End Class Module Example2 Public Sub Main() Dim p1 As New Person() p1.Name = "John" Dim p2 As Person = Nothing ' The following throws a NullReferenceException. Console.WriteLine("p1 = p2: {0}", p1.Equals(p2)) End Sub End Module
Kaynak kodu, NullReferenceException geçersiz kılmadan önce null için açıkça test edilecek şekilde değiştirilip yeniden derlendiğinde
obj
sırasında sonuçlanannull
istisnası ortadan kaldırılabilir. Aşağıdaki örnek, birnull
bağımsız değişkeni işleyen düzeltilmiş kaynak kodunu içerir.using System; public class Person2 { private string _name; public string Name { get { return _name; } set { _name = value; } } public override int GetHashCode() { return this.Name.GetHashCode(); } public override bool Equals(object obj) { // This implementation handles a null obj argument. Person2 p = obj as Person2; if (p == null) return false; else return this.Name.Equals(p.Name); } } public class UsageErrorsEx2 { public static void Main() { Person2 p1 = new Person2(); p1.Name = "John"; Person2 p2 = null; Console.WriteLine($"p1 = p2: {p1.Equals(p2)}"); } } // The example displays the following output: // p1 = p2: False
// In F#, null is not a valid state for declared types // without 'AllowNullLiteralAttribute' [<AllowNullLiteral>] type Person() = member val Name = "" with get, set override this.GetHashCode() = this.Name.GetHashCode() override this.Equals(obj) = // This implementation handles a null obj argument. match obj with | :? Person as p -> this.Name.Equals p.Name | _ -> false let p1 = Person() p1.Name <- "John" let p2: Person = null printfn $"p1 = p2: {p1.Equals p2}" // The example displays the following output: // p1 = p2: False
Public Class Person2 Private _name As String Public Property Name As String Get Return _name End Get Set _name = Value End Set End Property Public Overrides Function Equals(obj As Object) As Boolean ' This implementation handles a null obj argument. Dim p As Person2 = TryCast(obj, Person2) If p Is Nothing Then Return False Else Return Me.Name.Equals(p.Name) End If End Function End Class Module Example3 Public Sub Main() Dim p1 As New Person2() p1.Name = "John" Dim p2 As Person2 = Nothing Console.WriteLine("p1 = p2: {0}", p1.Equals(p2)) End Sub End Module ' The example displays the following output: ' p1 = p2: False
Hata ayıklama derlemelerindeki kullanım hatalarını tanımlamak için Debug.Assert yöntemini ve hem hata ayıklama hem de yayın derlemelerindeki kullanım hatalarını belirlemek için Trace.Assert yöntemini kullanabilir, kullanım hataları için özel durum işleme kullanmaktan kaçınabilirsiniz. Daha fazla bilgi için bkz. Yönetilen Kodda Onaylar.
Program hataları. Program hatası, hatasız kod yazarak mutlaka kaçınılamayan bir çalışma zamanı hatasıdır.
Bazı durumlarda, program hatası beklenen veya rutin bir hata koşulunu yansıtabilir. Bu durumda, program hatasıyla başa çıkmak için özel durum işleme kullanmaktan kaçınmak ve bunun yerine işlemi yeniden denemek isteyebilirsiniz. Örneğin, kullanıcının belirli bir biçimde tarih girmesi bekleniyorsa, DateTime.TryParseExact yöntemini çağırarak tarih dizesini ayrıştırabilirsiniz. Bu yöntem, ayrıştırma işleminin başarılı olup olmadığını gösteren bir Boolean değer döndürür. Tarih dizesi bir DateTime.ParseExact değerine dönüştürülemezse, FormatException istisnası oluşturan DateTime yöntemini kullanmak yerine bu yaklaşımı tercih edin. Benzer şekilde, bir kullanıcı var olmayan bir dosyayı açmaya çalışırsa, önce dosyanın var olup olmadığını denetlemek için yöntemini çağırabilir File.Exists ve yoksa, kullanıcıya oluşturmak isteyip istemediğini sorabilirsiniz.
Diğer durumlarda, program hatası kodunuzda işlenebilen beklenmeyen bir hata koşulunu yansıtır. Örneğin, bir dosyanın var olduğundan emin olmak için denetlemiş olsanız bile, dosyayı açabilmeniz için önce silinebilir veya bozulmuş olabilir. Bu durumda, bir StreamReader nesne örneği oluşturarak veya Open yöntemini çağırarak dosyayı açmaya çalışmak bir FileNotFoundException özel durumu fırlatabilir. Bu gibi durumlarda, hatadan kurtarmak için özel durum işlemeyi kullanmanız gerekir.
Sistem hataları. Sistem hatası, program aracılığıyla anlamlı bir şekilde işlenemeyen bir çalışma zamanı hatasıdır. Örneğin, ortak dil çalışma zamanı ek bellek ayıramıyorsa herhangi bir yöntem bir OutOfMemoryException istisnası oluşturabilir. Normalde sistem hataları özel durum işleme kullanılarak işlenmez. Bunun yerine, uygulama sonlandırılmadan önce özel durum bilgilerini günlüğe kaydetmek ve kullanıcıya hatayı bildirmek için AppDomain.UnhandledException gibi bir olayı kullanabilir ve Environment.FailFast yöntemini çağırabilirsiniz.
Try/catch blokları
Ortak dil çalışma zamanı, özel durumların nesneler olarak temsilini ve program kodu ile özel durum işleme try
kodunun bloklara ve catch
bloklara ayrılmasını temel alan bir özel durum işleme modeli sağlar. Her biri belirli bir özel durum türünü işlemek üzere tasarlanmış bir veya daha fazla catch
blok veya başka bir bloktan daha özel bir özel durum yakalamak için tasarlanmış bir blok olabilir.
Bir uygulama, bir uygulama kodu bloğunun yürütülmesi sırasında oluşan özel durumları işlerse, kod bir try
deyimi içine yerleştirilmelidir ve blok olarak adlandırılır try
. Bir try
blok tarafından oluşturulan özel durumları işleyen uygulama kodu, bir catch
deyimi içine yerleştirilir ve catch
bloğu olarak adlandırılır. Sıfır veya daha fazla catch
blok bir try
blokla ilişkilendirilir ve her catch
blok, işlediği özel durum türlerini belirleyen bir tür filtresi içerir.
Bir try
blokta özel durum oluştuğunda sistem, özel durumu işleyen bir catch
blok bulana kadar ilişkili catch
blokları uygulama kodunda göründükleri sırayla arar. Bir catch
bloğu, catch bloğunun tür filtresi T
veya ondan türeyen herhangi bir tür ise T
türündeki bir özel durumu işler. Sistem, özel durumu işleyen ilk catch
bloğu bulduklarından sonra aramayı durdurur. Bu nedenle, uygulama kodunda, bu bölümü izleyen örnekte gösterildiği gibi, catch
bir türü işleyen bir bloğun temel türlerini işleyen bir catch
blok öncesinde belirtilmesi gerekir.
System.Exception
işlemek üzere bir catch bloğu en son belirtilir.
Geçerli catch
blokla ilişkili try
blokların hiçbiri istisnayı işlemezse, ve geçerli try
blok geçerli çağrıdaki diğer try
blokların içinde iç içe yerleştirilmişse, bir sonraki kapsayıcı catch
blokla ilişkili try
bloklar aranır. Özel durum için bir catch
blok bulunmazsa, sistem mevcut çağrı içindeki önceki iç içe yerleştirme seviyelerini arar. Geçerli çağrıda özel durum için hiçbir catch
blok bulunmazsa, özel durum çağrı yığınına geçirilir ve önceki yığın çerçevesi özel durumu işleyen bir catch
blok için aranılır. Çağrı yığını araması, özel durum işlenene kadar veya çağrı yığınında başka çerçeve kalmayıncaya kadar devam eder. Çağrı yığınının en üstüne özel durumu işleyen bir catch
blok bulunmaksızın ulaşılırsa, varsayılan özel durum işleyicisi bunu işler ve uygulama sonlandırılır.
F# deneyin.. ifade ile
F# blokları kullanmaz catch
. Bunun yerine, yükseltilmiş bir özel durum deseni tek with
bir blok kullanılarak eşleştirilir. Bu bir ifade olduğundan, tüm yolların aynı türü döndürmesi gerekir. Daha fazla bilgi edinmek için bkz. try...with ifadesi.
Özel durum türü özellikleri
Özel durum türleri aşağıdaki özellikleri destekler:
Hatayı açıklayan, okunabilir metin. Bir özel durum oluştuğunda, çalışma zamanı kullanıcıyı hatanın doğası hakkında bilgilendirmek ve sorunu çözmek için eylem önermek için bir kısa mesaj sağlar. Bu metin iletisi özel durum nesnesinin özelliğinde Message tutulur. Özel durum nesnesinin oluşturulması sırasında, bu özel durumun ayrıntılarını açıklamak için oluşturucuya bir metin dizesi geçirebilirsiniz. Oluşturucuya bir hata mesajı argümanı sağlanmadıysa, varsayılan hata mesajı kullanılır. Daha fazla bilgi için Message özelliğine bakın.
İstisna fırlatıldığında çağrı yığınının durumu. özelliği, StackTrace hatanın kodda nerede oluştuğuna karar vermek için kullanılabilecek bir yığın izlemesi taşır. Yığın izlemesi, çağrılan tüm yöntemleri ve çağrıların yapıldığı kaynak dosyadaki satır numaralarını listeler.
İstisna sınıfı özellikleri
sınıfı Exception , kod konumunu, türünü, yardım dosyasını ve özel durumun nedenini tanımlamaya yardımcı olan bir dizi özellik içerir: StackTrace, InnerException, Message, HelpLink, HResult, , Source, TargetSiteve Data.
İki veya daha fazla özel durum arasında nedensel ilişki varsa, InnerException özelliği bu bilgileri korur. Dış özel durum, bu iç özel duruma yanıt olarak oluşturulur. Dış özel durumu işleyen kod, hatayı daha uygun bir şekilde işlemek için önceki iç özel durumdaki bilgileri kullanabilir. Özel durumla ilgili ek bilgiler, özelliğinde Data anahtar/değer çiftleri koleksiyonu olarak depolanabilir.
Özel durum nesnesi oluşturulurken oluşturucuya geçirilen hata iletisi dizesi yerelleştirilmelidir ve sınıfı kullanılarak bir kaynak dosyasından ResourceManager sağlanabilir. Yerelleştirilmiş kaynaklar hakkında daha fazla bilgi için Uydu Derlemeleri Oluşturma ve Kaynakları Paketleme ve Dağıtma konularına bakın.
Kullanıcıya özel durumun neden oluştuğu hakkında kapsamlı bilgiler sağlamak için, özellik bir yardım dosyasının HelpLink URL'sini (veya URN'sini) tutabilir.
Exception sınıfı, 0x80131500 değerine sahip olan HRESULT COR_E_EXCEPTION
'ü kullanır.
Sınıfının bir örneğinin ilk özellik değerlerinin Exception listesi için oluşturuculara Exception bakın.
Performansla ilgili dikkat edilmesi gerekenler
Özel durum oluşturma veya işleme, önemli miktarda sistem kaynağı ve yürütme süresi tüketir. Öngörülebilir olayları veya akış kontrolünü yönetmek için değil, yalnızca gerçekten olağanüstü durumları ele almak için istisnalar atın. Örneğin, bir sınıf kitaplığı geliştirirken olduğu gibi bazı durumlarda, yönteminizin geçerli parametrelerle çağrılmasını beklediğiniz için bir yöntem bağımsız değişkeni geçersizse bir özel durum oluşturmak mantıklıdır. Geçersiz bir yöntem bağımsız değişkeni, eğer bir kullanım hatasının sonucu değilse, olağanüstü bir şey yaşandığı anlamına gelir. Buna karşılık, kullanıcı girişi geçersizse bir özel durum oluşturmayın, çünkü kullanıcıların bazen geçersiz veri girmesini bekleyebilirsiniz. Bunun yerine, kullanıcıların geçerli giriş girebilmesi için bir yeniden deneme mekanizması sağlayın. Kullanım hatalarını işlemek için özel durumları da kullanmamalısınız. Bunun yerine, kullanım hatalarını tanımlamak ve düzeltmek için doğrulama kullanın.
Ayrıca, bir dönüş kodu yeterli olduğunda özel durum oluşturmayın; dönüş kodunu özel duruma dönüştürmeyin; ve rutin olarak bir özel durum yakalamayın, yok saymayın ve işlemeye devam etmeyin.
Özel durumu yeniden oluşturma
Çoğu durumda, bir özel durum işleyicisi sadece istisnayı çağırana iletmek ister. Bu en sık şu durumlarda oluşur:
.NET sınıf kitaplığındaki veya diğer sınıf kitaplıklarındaki yöntemlere çağrıları saran bir sınıf kitaplığı.
Ölümcül bir özel durumla karşılaşan bir uygulama veya kitaplık. Özel durum işleyicisi özel durumu günlüğe kaydedebilir ve ardından özel durumu yeniden fırlatabilir.
Bir özel durumu yeniden oluşturmanın önerilen yolu C# dilinde throw deyimini, F# dilinde reraise işlevini ve Bir ifade eklemeden Visual Basic'te Throw deyimini kullanmaktır. Bu, özel durum çağırana yayıldığında tüm çağrı yığını bilgilerinin korunmasını sağlar. Aşağıdaki örnekte bu gösterilmektedir. dize uzantısı yöntemi, bağımsız değişkenlerini önceden doğrulamadan bir veya daha fazla FindOccurrences
çağrısını String.IndexOf(String, Int32) içine sarar.
using System;
using System.Collections.Generic;
public static class Library1
{
public static int[] FindOccurrences(this String s, String f)
{
var indexes = new List<int>();
int currentIndex = 0;
try
{
while (currentIndex >= 0 && currentIndex < s.Length)
{
currentIndex = s.IndexOf(f, currentIndex);
if (currentIndex >= 0)
{
indexes.Add(currentIndex);
currentIndex++;
}
}
}
catch (ArgumentNullException)
{
// Perform some action here, such as logging this exception.
throw;
}
return indexes.ToArray();
}
}
open System
module Library =
let findOccurrences (s: string) (f: string) =
let indexes = ResizeArray()
let mutable currentIndex = 0
try
while currentIndex >= 0 && currentIndex < s.Length do
currentIndex <- s.IndexOf(f, currentIndex)
if currentIndex >= 0 then
indexes.Add currentIndex
currentIndex <- currentIndex + 1
with :? ArgumentNullException ->
// Perform some action here, such as logging this exception.
reraise ()
indexes.ToArray()
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices
Public Module Library
<Extension()>
Public Function FindOccurrences1(s As String, f As String) As Integer()
Dim indexes As New List(Of Integer)
Dim currentIndex As Integer = 0
Try
Do While currentIndex >= 0 And currentIndex < s.Length
currentIndex = s.IndexOf(f, currentIndex)
If currentIndex >= 0 Then
indexes.Add(currentIndex)
currentIndex += 1
End If
Loop
Catch e As ArgumentNullException
' Perform some action here, such as logging this exception.
Throw
End Try
Return indexes.ToArray()
End Function
End Module
Bir arayan daha sonra iki kez arar FindOccurrences
.
FindOccurrences
öğesine yapılan ikinci çağrıda, çağıran bir null
arama dizesi olarak geçirir ve bu da String.IndexOf(String, Int32) yönteminin bir ArgumentNullException özel durum fırlatmasına neden olur. Bu istisna, FindOccurrences
yöntemi tarafından ele alınır ve çağırana geri iletilir. Throw deyimi ifade olmadan kullanıldığından, örnekteki çıkış çağrı yığınının korunduğunu gösterir.
public class RethrowEx1
{
public static void Main()
{
String s = "It was a cold day when...";
int[] indexes = s.FindOccurrences("a");
ShowOccurrences(s, "a", indexes);
Console.WriteLine();
String toFind = null;
try
{
indexes = s.FindOccurrences(toFind);
ShowOccurrences(s, toFind, indexes);
}
catch (ArgumentNullException e)
{
Console.WriteLine($"An exception ({e.GetType().Name}) occurred.");
Console.WriteLine($"Message:{Environment.NewLine} {e.Message}{Environment.NewLine}");
Console.WriteLine($"Stack Trace:{Environment.NewLine} {e.StackTrace}{Environment.NewLine}");
}
}
private static void ShowOccurrences(String s, String toFind, int[] indexes)
{
Console.Write("'{0}' occurs at the following character positions: ",
toFind);
for (int ctr = 0; ctr < indexes.Length; ctr++)
Console.Write("{0}{1}", indexes[ctr],
ctr == indexes.Length - 1 ? "" : ", ");
Console.WriteLine();
}
}
// The example displays the following output:
// 'a' occurs at the following character positions: 4, 7, 15
//
// An exception (ArgumentNullException) occurred.
// Message:
// Value cannot be null.
// Parameter name: value
//
// Stack Trace:
// at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
// ngComparison comparisonType)
// at Library.FindOccurrences(String s, String f)
// at Example.Main()
open Library
let showOccurrences toFind (indexes: int[]) =
printf $"'{toFind}' occurs at the following character positions: "
for i = 0 to indexes.Length - 1 do
printf $"""{indexes[i]}{if i = indexes.Length - 1 then "" else ", "}"""
printfn ""
let s = "It was a cold day when..."
let indexes = findOccurrences s "a"
showOccurrences "a" indexes
printfn ""
let toFind: string = null
try
let indexes = findOccurrences s toFind
showOccurrences toFind indexes
with :? ArgumentNullException as e ->
printfn $"An exception ({e.GetType().Name}) occurred."
printfn $"Message:\n {e.Message}\n"
printfn $"Stack Trace:\n {e.StackTrace}\n"
// The example displays the following output:
// 'a' occurs at the following character positions: 4, 7, 15
//
// An exception (ArgumentNullException) occurred.
// Message:
// Value cannot be null. (Parameter 'value')
//
// Stack Trace:
// at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
// ngComparison comparisonType)
// at Library.findOccurrences(String s, String f)
// at <StartupCode$fs>.main@()
Module Example1
Public Sub Main()
Dim s As String = "It was a cold day when..."
Dim indexes() As Integer = s.FindOccurrences1("a")
ShowOccurrences(s, "a", indexes)
Console.WriteLine()
Dim toFind As String = Nothing
Try
indexes = s.FindOccurrences1(toFind)
ShowOccurrences(s, toFind, indexes)
Catch e As ArgumentNullException
Console.WriteLine("An exception ({0}) occurred.",
e.GetType().Name)
Console.WriteLine("Message:{0} {1}{0}", vbCrLf, e.Message)
Console.WriteLine("Stack Trace:{0} {1}{0}", vbCrLf, e.StackTrace)
End Try
End Sub
Private Sub ShowOccurrences(s As String, toFind As String, indexes As Integer())
Console.Write("'{0}' occurs at the following character positions: ",
toFind)
For ctr As Integer = 0 To indexes.Length - 1
Console.Write("{0}{1}", indexes(ctr),
If(ctr = indexes.Length - 1, "", ", "))
Next
Console.WriteLine()
End Sub
End Module
' The example displays the following output:
' 'a' occurs at the following character positions: 4, 7, 15
'
' An exception (ArgumentNullException) occurred.
' Message:
' Value cannot be null.
' Parameter name: value
'
' Stack Trace:
' at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
' ngComparison comparisonType)
' at Library.FindOccurrences(String s, String f)
' at Example.Main()
Buna karşılık, özel durum bu ifade kullanılarak yeniden atılırsa:
throw e;
Throw e
raise e
... ardından tam çağrı yığını korunmaz ve örnek aşağıdaki çıkışı oluşturur:
'a' occurs at the following character positions: 4, 7, 15
An exception (ArgumentNullException) occurred.
Message:
Value cannot be null.
Parameter name: value
Stack Trace:
at Library.FindOccurrences(String s, String f)
at Example.Main()
Biraz daha hantal bir alternatif, yeni bir özel durum oluşturmak ve özgün özel durumun çağrı yığını bilgilerini bir iç özel durumda korumaktır. Çağıran daha sonra yığın çerçevesini ve özgün özel durum hakkındaki diğer bilgileri almak için yeni özel durumun InnerException özelliğini kullanabilir. Bu durumda throw deyimi şöyledir:
throw new ArgumentNullException("You must supply a search string.", e);
raise (ArgumentNullException("You must supply a search string.", e) )
Throw New ArgumentNullException("You must supply a search string.",
e)
Aşağıdaki özel durum işleyicisinde gösterildiği gibi, özel durumu işleyen kullanıcı kodunun InnerException özelliğin özgün özel durum hakkında bilgi içerdiğini bilmesi gerekir.
try
{
indexes = s.FindOccurrences(toFind);
ShowOccurrences(s, toFind, indexes);
}
catch (ArgumentNullException e)
{
Console.WriteLine($"An exception ({e.GetType().Name}) occurred.");
Console.WriteLine($" Message:{Environment.NewLine}{e.Message}");
Console.WriteLine($" Stack Trace:{Environment.NewLine} {e.StackTrace}");
Exception ie = e.InnerException;
if (ie != null)
{
Console.WriteLine(" The Inner Exception:");
Console.WriteLine($" Exception Name: {ie.GetType().Name}");
Console.WriteLine($" Message: {ie.Message}{Environment.NewLine}");
Console.WriteLine($" Stack Trace:{Environment.NewLine} {ie.StackTrace}{Environment.NewLine}");
}
}
// The example displays the following output:
// 'a' occurs at the following character positions: 4, 7, 15
//
// An exception (ArgumentNullException) occurred.
// Message: You must supply a search string.
//
// Stack Trace:
// at Library.FindOccurrences(String s, String f)
// at Example.Main()
//
// The Inner Exception:
// Exception Name: ArgumentNullException
// Message: Value cannot be null.
// Parameter name: value
//
// Stack Trace:
// at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
// ngComparison comparisonType)
// at Library.FindOccurrences(String s, String f)
try
let indexes = findOccurrences s toFind
showOccurrences toFind indexes
with :? ArgumentNullException as e ->
printfn $"An exception ({e.GetType().Name}) occurred."
printfn $" Message:\n{e.Message}"
printfn $" Stack Trace:\n {e.StackTrace}"
let ie = e.InnerException
if ie <> null then
printfn " The Inner Exception:"
printfn $" Exception Name: {ie.GetType().Name}"
printfn $" Message: {ie.Message}\n"
printfn $" Stack Trace:\n {ie.StackTrace}\n"
// The example displays the following output:
// 'a' occurs at the following character positions: 4, 7, 15
//
// An exception (ArgumentNullException) occurred.
// Message: You must supply a search string.
//
// Stack Trace:
// at Library.FindOccurrences(String s, String f)
// at Example.Main()
//
// The Inner Exception:
// Exception Name: ArgumentNullException
// Message: Value cannot be null.
// Parameter name: value
//
// Stack Trace:
// at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
// ngComparison comparisonType)
// at Library.FindOccurrences(String s, String f)
Try
indexes = s.FindOccurrences(toFind)
ShowOccurrences(s, toFind, indexes)
Catch e As ArgumentNullException
Console.WriteLine("An exception ({0}) occurred.",
e.GetType().Name)
Console.WriteLine(" Message: {1}{0}", vbCrLf, e.Message)
Console.WriteLine(" Stack Trace:{0} {1}{0}", vbCrLf, e.StackTrace)
Dim ie As Exception = e.InnerException
If ie IsNot Nothing Then
Console.WriteLine(" The Inner Exception:")
Console.WriteLine(" Exception Name: {0}", ie.GetType().Name)
Console.WriteLine(" Message: {1}{0}", vbCrLf, ie.Message)
Console.WriteLine(" Stack Trace:{0} {1}{0}", vbCrLf, ie.StackTrace)
End If
End Try
' The example displays the following output:
' 'a' occurs at the following character positions: 4, 7, 15
'
' An exception (ArgumentNullException) occurred.
' Message: You must supply a search string.
'
' Stack Trace:
' at Library.FindOccurrences(String s, String f)
' at Example.Main()
'
' The Inner Exception:
' Exception Name: ArgumentNullException
' Message: Value cannot be null.
' Parameter name: value
'
' Stack Trace:
' at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
' ngComparison comparisonType)
' at Library.FindOccurrences(String s, String f)
Standart özel durumları seçme
Özel durum oluşturmanız gerektiğinde, özel bir özel durum uygulamak yerine .NET'te var olan bir özel durum türünü kullanabilirsiniz. Şu iki koşul altında standart bir özel durum türü kullanmalısınız:
Bir kullanım hatasının (yani, yönteminizi çağıran geliştirici tarafından yapılan program mantığındaki bir hatanın) neden olduğu bir istisna fırlatıyorsunuz. Genellikle ArgumentException, ArgumentNullException, InvalidOperationException veya NotSupportedException gibi bir özel durum fırlatırsınız. Özel durum nesnesinin örneğini oluştururken özel durum nesnesinin oluşturucusunun sağladığınız dize, geliştiricinin düzeltebilmesi için hatayı açıklamalıdır. Daha fazla bilgi için Message özelliğine bakın.
Var olan bir .NET özel durumuyla çağırana iletilebilen bir hatayı işliyorsunuz. Mümkün olan en türetilmiş özel durumu fırlatmalısınız. Örneğin, bir yöntem bir bağımsız değişkenin bir sabit listesi türünün geçerli bir üyesi olmasını gerektiriyorsa, bir InvalidEnumArgumentException yerine bir ArgumentException (en türetilmiş sınıf) oluşturmanız gerekir.
Aşağıdaki tabloda yaygın istisna türleri ve hangi koşullarda fırlatılacağı listelenmiştir.
İstisna | Koşul |
---|---|
ArgumentException | Bir yönteme geçirilen null olmayan bağımsız değişken geçersiz. |
ArgumentNullException | Bir yönteme geçirilen bağımsız değişken: null . |
ArgumentOutOfRangeException | Bir argüman geçerli değer aralığının dışındadır. |
DirectoryNotFoundException | Dizin yolunun bir bölümü geçerli değil. |
DivideByZeroException | Tamsayı veya Decimal bölme işlemindeki payda sıfırdır. |
DriveNotFoundException | Disk kullanılamıyor veya mevcut değil. |
FileNotFoundException | Dosya yok. |
FormatException | Değer, Parse gibi bir dönüştürme yöntemiyle bir dizeden dönüştürülebilecek uygun biçimde değildir. |
IndexOutOfRangeException | Bir dizin, bir dizi veya koleksiyonun sınırlarının dışında. |
InvalidOperationException | Yöntem çağrısı, nesnenin geçerli durumunda geçersiz. |
KeyNotFoundException | Koleksiyondaki bir üyeye erişmek için belirtilen anahtar bulunamıyor. |
NotImplementedException | Yöntem veya işlem uygulanmaz. |
NotSupportedException | Yöntem veya işlem desteklenmez. |
ObjectDisposedException | Yok edilmiş bir nesne üzerinde bir işlem gerçekleştirilir. |
OverflowException | Aritmetik, türetme veya dönüştürme işlemi taşmayla sonuçlanmasıdır. |
PathTooLongException | Yol veya dosya adı, sistem tanımlı uzunluk üst sınırını aşıyor. |
PlatformNotSupportedException | İşlem geçerli platformda desteklenmiyor. |
RankException | Bir yönteme yanlış sayıda boyuta sahip bir dizi geçirilir. |
TimeoutException | Bir işleme ayrılan zaman aralığının süresi doldu. |
UriFormatException | Geçersiz bir Tekdüzen Kaynak Tanımlayıcısı (URI) kullanılıyor. |
Özel istisnalar uygulama
Aşağıdaki durumlarda, bir hata koşulunu işlemek için mevcut bir .NET özel durumunu kullanmak yeterli değildir:
Özel durum, mevcut bir .NET özel durumuyla eşlenemeyen benzersiz bir program hatasını yansıttığında.
Özel durum, var olan bir .NET özel durumu için uygun işlemeden farklı bir işleme gerektirdiğinde veya özel durumun benzer bir özel durumdan belirsiz olması gerektiğinde. Örneğin, hedef tam sayı türünün aralığının dışında olan bir dizenin sayısal gösterimini ayrıştırırken özel ArgumentOutOfRangeException durum oluşturursanız, çağıranın yöntemini çağırırken uygun kısıtlanmış değerleri sağlamamasıyla sonuçlanan bir hata için aynı özel durumu kullanmak istemezsiniz.
Exception sınıfı, .NET'teki tüm özel durumların temel sınıfıdır. Birçok türetilmiş sınıf, Exception sınıfının üyelerinin devralınan davranışına dayanır; üyelerini Exception geçersiz kılmaz, benzersiz üyeler de tanımlamaz.
Kendi özel durum sınıfınızı tanımlamak için:
öğesinden Exceptiondevralan bir sınıf tanımlayın. Gerekirse, özel durum hakkında ek bilgi sağlamak için sınıfınızın ihtiyaç duyduğu benzersiz üyeleri tanımlayın. Örneğin, ArgumentException sınıfı, özel duruma neden olan bağımsız değişkenin adını belirten bir ParamName özelliği ve zaman aşımı aralığını belirten bir RegexMatchTimeoutException özelliği içeren bir MatchTimeout özelliği içerir.
Gerekirse, işlevselliğini değiştirmek istediğiniz devralınan üyeleri geçersiz kılın. Çoğu varolan türetilmiş sınıfların Exception devralınan üyelerin davranışını geçersiz kılmadığını unutmayın.
Özelleştirilmiş özel durum nesnenizin serileştirilebilir olup olmadığını belirleyin. Seri hale getirme, özel durum hakkındaki bilgileri kaydetmenizi sağlar ve uzaktan iletişim bağlamında bir sunucu ve istemci proxy'si tarafından özel durum bilgilerinin paylaşılmasına izin verir. Özel durum nesnesini seri hale getirmek için özniteliğiyle SerializableAttribute işaretleyin.
Özel durum sınıfınızın oluşturucularını tanımlayın. Genellikle, özel durum sınıflarının aşağıdaki oluşturuculardan biri veya daha fazlası vardır:
Exception(), yeni bir özel durum nesnesinin özelliklerini başlatmak için varsayılan değerleri kullanır.
Exception(String), belirtilen hata iletisiyle yeni bir özel durum nesnesi başlatır.
Exception(String, Exception), belirtilen hata iletisi ve iç özel durum ile yeni bir özel durum nesnesi başlatır.
Exception(SerializationInfo, StreamingContext), serileştirilmiş verilerden yeni bir özel durum nesnesi başlatan bir
protected
oluşturucudur. Özel durum nesnenizi serileştirilebilir yapmayı seçtiyseniz bu oluşturucuyu uygulamanız gerekir.
Aşağıdaki örnekte özel bir özel durum sınıfının kullanımı gösterilmektedir. İstemci, asal olmayan bir NotPrimeException
başlangıç numarası belirterek bir dizi asal sayı almaya çalıştığında oluşan bir özel durum tanımlar. Özel durum, NonPrime
özel duruma neden olan asal olmayan sayıyı döndüren yeni bir özelliği tanımlar. Serileştirme için korumalı bir parametresiz oluşturucu ve SerializationInfo ve StreamingContext parametreleriyle bir oluşturucu uygulamanın yanı sıra, NotPrimeException
sınıfı, NonPrime
özelliğini desteklemek için üç ek oluşturucu tanımlar. Her oluşturucu, asal olmayan sayının değerini korumaya ek olarak bir temel sınıf oluşturucu çağırır.
NotPrimeException
sınıfı, SerializableAttribute özniteliğiyle de işaretlenir.
using System;
using System.Runtime.Serialization;
[Serializable()]
public class NotPrimeException : Exception
{
private int notAPrime;
protected NotPrimeException()
: base()
{ }
public NotPrimeException(int value) :
base(String.Format("{0} is not a prime number.", value))
{
notAPrime = value;
}
public NotPrimeException(int value, string message)
: base(message)
{
notAPrime = value;
}
public NotPrimeException(int value, string message, Exception innerException) :
base(message, innerException)
{
notAPrime = value;
}
protected NotPrimeException(SerializationInfo info,
StreamingContext context)
: base(info, context)
{ }
public int NonPrime
{ get { return notAPrime; } }
}
namespace global
open System
open System.Runtime.Serialization
[<Serializable>]
type NotPrimeException =
inherit Exception
val notAPrime: int
member this.NonPrime =
this.notAPrime
new (value) =
{ inherit Exception($"%i{value} is not a prime number."); notAPrime = value }
new (value, message) =
{ inherit Exception(message); notAPrime = value }
new (value, message, innerException: Exception) =
{ inherit Exception(message, innerException); notAPrime = value }
// F# does not support protected members
new () =
{ inherit Exception(); notAPrime = 0 }
new (info: SerializationInfo, context: StreamingContext) =
{ inherit Exception(info, context); notAPrime = 0 }
Imports System.Runtime.Serialization
<Serializable()> _
Public Class NotPrimeException : Inherits Exception
Private notAPrime As Integer
Protected Sub New()
MyBase.New()
End Sub
Public Sub New(value As Integer)
MyBase.New(String.Format("{0} is not a prime number.", value))
notAPrime = value
End Sub
Public Sub New(value As Integer, message As String)
MyBase.New(message)
notAPrime = value
End Sub
Public Sub New(value As Integer, message As String, innerException As Exception)
MyBase.New(message, innerException)
notAPrime = value
End Sub
Protected Sub New(info As SerializationInfo,
context As StreamingContext)
MyBase.New(info, context)
End Sub
Public ReadOnly Property NonPrime As Integer
Get
Return notAPrime
End Get
End Property
End Class
PrimeNumberGenerator
Aşağıdaki örnekte gösterilen sınıf, 2 ile istemci tarafından sınıf oluşturucusunun çağrısında belirtilen sınıra kadar olan asal sayıların dizisini hesaplamak için Eratosthenes Eleği'ni kullanır. yöntemi, GetPrimesFrom
belirtilen alt sınırdan büyük veya buna eşit olan tüm asal sayıları döndürür, ancak bu alt sınır bir asal sayı değilse bir NotPrimeException
atar.
using System;
using System.Collections.Generic;
[Serializable]
public class PrimeNumberGenerator
{
private const int START = 2;
private int maxUpperBound = 10000000;
private int upperBound;
private bool[] primeTable;
private List<int> primes = new List<int>();
public PrimeNumberGenerator(int upperBound)
{
if (upperBound > maxUpperBound)
{
string message = String.Format(
"{0} exceeds the maximum upper bound of {1}.",
upperBound, maxUpperBound);
throw new ArgumentOutOfRangeException(message);
}
this.upperBound = upperBound;
// Create array and mark 0, 1 as not prime (True).
primeTable = new bool[upperBound + 1];
primeTable[0] = true;
primeTable[1] = true;
// Use Sieve of Eratosthenes to determine prime numbers.
for (int ctr = START; ctr <= (int)Math.Ceiling(Math.Sqrt(upperBound));
ctr++)
{
if (primeTable[ctr]) continue;
for (int multiplier = ctr; multiplier <= upperBound / ctr; multiplier++)
if (ctr * multiplier <= upperBound) primeTable[ctr * multiplier] = true;
}
// Populate array with prime number information.
int index = START;
while (index != -1)
{
index = Array.FindIndex(primeTable, index, (flag) => !flag);
if (index >= 1)
{
primes.Add(index);
index++;
}
}
}
public int[] GetAllPrimes()
{
return primes.ToArray();
}
public int[] GetPrimesFrom(int prime)
{
int start = primes.FindIndex((value) => value == prime);
if (start < 0)
throw new NotPrimeException(prime, String.Format("{0} is not a prime number.", prime));
else
return primes.FindAll((value) => value >= prime).ToArray();
}
}
namespace global
open System
[<Serializable>]
type PrimeNumberGenerator(upperBound) =
let start = 2
let maxUpperBound = 10000000
let primes = ResizeArray()
let primeTable =
upperBound + 1
|> Array.zeroCreate<bool>
do
if upperBound > maxUpperBound then
let message = $"{upperBound} exceeds the maximum upper bound of {maxUpperBound}."
raise (ArgumentOutOfRangeException message)
// Create array and mark 0, 1 as not prime (True).
primeTable[0] <- true
primeTable[1] <- true
// Use Sieve of Eratosthenes to determine prime numbers.
for i = start to float upperBound |> sqrt |> ceil |> int do
if not primeTable[i] then
for multiplier = i to upperBound / i do
if i * multiplier <= upperBound then
primeTable[i * multiplier] <- true
// Populate array with prime number information.
let mutable index = start
while index <> -1 do
index <- Array.FindIndex(primeTable, index, fun flag -> not flag)
if index >= 1 then
primes.Add index
index <- index + 1
member _.GetAllPrimes() =
primes.ToArray()
member _.GetPrimesFrom(prime) =
let start =
Seq.findIndex ((=) prime) primes
if start < 0 then
raise (NotPrimeException(prime, $"{prime} is not a prime number.") )
else
Seq.filter ((>=) prime) primes
|> Seq.toArray
Imports System.Collections.Generic
<Serializable()> Public Class PrimeNumberGenerator
Private Const START As Integer = 2
Private maxUpperBound As Integer = 10000000
Private upperBound As Integer
Private primeTable() As Boolean
Private primes As New List(Of Integer)
Public Sub New(upperBound As Integer)
If upperBound > maxUpperBound Then
Dim message As String = String.Format(
"{0} exceeds the maximum upper bound of {1}.",
upperBound, maxUpperBound)
Throw New ArgumentOutOfRangeException(message)
End If
Me.upperBound = upperBound
' Create array and mark 0, 1 as not prime (True).
ReDim primeTable(upperBound)
primeTable(0) = True
primeTable(1) = True
' Use Sieve of Eratosthenes to determine prime numbers.
For ctr As Integer = START To CInt(Math.Ceiling(Math.Sqrt(upperBound)))
If primeTable(ctr) Then Continue For
For multiplier As Integer = ctr To CInt(upperBound \ ctr)
If ctr * multiplier <= upperBound Then primeTable(ctr * multiplier) = True
Next
Next
' Populate array with prime number information.
Dim index As Integer = START
Do While index <> -1
index = Array.FindIndex(primeTable, index, Function(flag)
Return Not flag
End Function)
If index >= 1 Then
primes.Add(index)
index += 1
End If
Loop
End Sub
Public Function GetAllPrimes() As Integer()
Return primes.ToArray()
End Function
Public Function GetPrimesFrom(prime As Integer) As Integer()
Dim start As Integer = primes.FindIndex(Function(value)
Return value = prime
End Function)
If start < 0 Then
Throw New NotPrimeException(prime, String.Format("{0} is not a prime number.", prime))
Else
Return primes.FindAll(Function(value)
Return value >= prime
End Function).ToArray()
End If
End Function
End Class
Aşağıdaki örnek, asal olmayan numaralarla yöntemine GetPrimesFrom
iki çağrı yapar ve bunlardan biri uygulama etki alanı sınırlarını geçer. Her iki durumda da özel durum oluşturulur ve istemci kodunda başarıyla işlenir.
using System;
using System.Reflection;
class Example1
{
public static void Main()
{
int limit = 10000000;
PrimeNumberGenerator primes = new PrimeNumberGenerator(limit);
int start = 1000001;
try
{
int[] values = primes.GetPrimesFrom(start);
Console.WriteLine($"There are {start} prime numbers from {limit} to {2}");
}
catch (NotPrimeException e)
{
Console.WriteLine($"{e.NonPrime} is not prime");
Console.WriteLine(e);
Console.WriteLine("--------");
}
AppDomain domain = AppDomain.CreateDomain("Domain2");
PrimeNumberGenerator gen = (PrimeNumberGenerator)domain.CreateInstanceAndUnwrap(
typeof(Example).Assembly.FullName,
"PrimeNumberGenerator", true,
BindingFlags.Default, null,
new object[] { 1000000 }, null, null);
try
{
start = 100;
Console.WriteLine(gen.GetPrimesFrom(start));
}
catch (NotPrimeException e)
{
Console.WriteLine($"{e.NonPrime} is not prime");
Console.WriteLine(e);
Console.WriteLine("--------");
}
}
}
open System
open System.Reflection
let limit = 10000000
let primes = PrimeNumberGenerator limit
let start = 1000001
try
let values = primes.GetPrimesFrom start
printfn $"There are {values.Length} prime numbers from {start} to {limit}"
with :? NotPrimeException as e ->
printfn $"{e.NonPrime} is not prime"
printfn $"{e}"
printfn "--------"
let domain = AppDomain.CreateDomain "Domain2"
let gen =
domain.CreateInstanceAndUnwrap(
typeof<PrimeNumberGenerator>.Assembly.FullName,
"PrimeNumberGenerator", true,
BindingFlags.Default, null,
[| box 1000000 |], null, null)
:?> PrimeNumberGenerator
try
let start = 100
printfn $"{gen.GetPrimesFrom start}"
with :? NotPrimeException as e ->
printfn $"{e.NonPrime} is not prime"
printfn $"{e}"
printfn "--------"
Imports System.Reflection
Module Example
Sub Main()
Dim limit As Integer = 10000000
Dim primes As New PrimeNumberGenerator(limit)
Dim start As Integer = 1000001
Try
Dim values() As Integer = primes.GetPrimesFrom(start)
Console.WriteLine("There are {0} prime numbers from {1} to {2}",
start, limit)
Catch e As NotPrimeException
Console.WriteLine("{0} is not prime", e.NonPrime)
Console.WriteLine(e)
Console.WriteLine("--------")
End Try
Dim domain As AppDomain = AppDomain.CreateDomain("Domain2")
Dim gen As PrimeNumberGenerator = domain.CreateInstanceAndUnwrap(
GetType(Example).Assembly.FullName,
"PrimeNumberGenerator", True,
BindingFlags.Default, Nothing,
{1000000}, Nothing, Nothing)
Try
start = 100
Console.WriteLine(gen.GetPrimesFrom(start))
Catch e As NotPrimeException
Console.WriteLine("{0} is not prime", e.NonPrime)
Console.WriteLine(e)
Console.WriteLine("--------")
End Try
End Sub
End Module
' The example displays the following output:
' 1000001 is not prime
' NotPrimeException: 1000001 is not a prime number.
' at PrimeNumberGenerator.GetPrimesFrom(Int32 prime)
' at Example.Main()
' --------
' 100 is not prime
' NotPrimeException: 100 is not a prime number.
' at PrimeNumberGenerator.GetPrimesFrom(Int32 prime)
' at Example.Main()
' --------
Örnekler
Aşağıdaki örnek, catch
hatalarını işlemek üzere tanımlanan bir with
bloğunu gösterir (F#'ta ArithmeticException). Bu catch
blok, DivideByZeroException hataları da yakalar, çünkü DivideByZeroException, ArithmeticException türetilir ve catch
hataları için açıkça tanımlanmış bir DivideByZeroException blok yoktur.
using System;
class ExceptionTestClass
{
public static void Main()
{
int x = 0;
try
{
int y = 100 / x;
}
catch (ArithmeticException e)
{
Console.WriteLine($"ArithmeticException Handler: {e}");
}
catch (Exception e)
{
Console.WriteLine($"Generic Exception Handler: {e}");
}
}
}
/*
This code example produces the following results:
ArithmeticException Handler: System.DivideByZeroException: Attempted to divide by zero.
at ExceptionTestClass.Main()
*/
module ExceptionTestModule
open System
let x = 0
try
let y = 100 / x
()
with
| :? ArithmeticException as e ->
printfn $"ArithmeticException Handler: {e}"
| e ->
printfn $"Generic Exception Handler: {e}"
// This code example produces the following results:
// ArithmeticException Handler: System.DivideByZeroException: Attempted to divide by zero.
// at <StartupCode$fs>.$ExceptionTestModule.main@()
Class ExceptionTestClass
Public Shared Sub Main()
Dim x As Integer = 0
Try
Dim y As Integer = 100 / x
Catch e As ArithmeticException
Console.WriteLine("ArithmeticException Handler: {0}", e.ToString())
Catch e As Exception
Console.WriteLine("Generic Exception Handler: {0}", e.ToString())
End Try
End Sub
End Class
'
'This code example produces the following results:
'
'ArithmeticException Handler: System.OverflowException: Arithmetic operation resulted in an overflow.
' at ExceptionTestClass.Main()
'