Alıştırma - Belirli özel durum türlerini yakalama

Tamamlandı

Bu modülün önceki bölümlerinde, C# uygulamanız tarafından yakalanan özel durum nesnelerinin bir özel durum sınıfının örnekleri olduğunu öğrendiniz. Genel olarak, kodunuz aşağıdakilerden birini yapar catch :

  • System.Exception taban sınıfının bir örneği olan bir istisna nesnesi.
  • Temel sınıftan devralan bir özel durum türünün örneği olan bir özel durum nesnesi. Örneğin InvalidCastException sınıfının bir örneği.

Özel durum özelliklerini inceleme

System.Exception tüm türetilmiş özel durum türlerinin devraldığı temel sınıftır. Her özel durum türü, belirli bir sınıf hiyerarşisi aracılığıyla temel sınıftan devralır. Örneğin, için InvalidCastException sınıf hiyerarşisi aşağıdaki gibidir:

Object
    Exception
        SystemException
            InvalidCastException

öğesinden Exception devralan özel durum sınıflarının çoğu ek işlevsellik eklemez; yalnızca öğesinden Exceptiondevralır. Bu nedenle, sınıfın Exception özelliklerini incelemek çoğu özel durumu ve kodunuzda bir özel durumu nasıl kullanabileceğinizi anlamanıza olanak tanır.

İşte Exception sınıfının özellikleri:

  • Veri: Data özelliği anahtar-değer çiftlerinde rastgele veriler barındırıyor.
  • HelpLink: Özelliği HelpLink , bir özel durumun nedeni hakkında kapsamlı bilgi sağlayan bir yardım dosyasının URL'sini (veya URN'sini) tutmak için kullanılabilir.
  • HResult: özelliği, HResult belirli bir özel duruma atanan kodlanmış sayısal değere erişmek için kullanılabilir.
  • InnerException: özelliği, InnerException özel durum işleme sırasında bir dizi özel durum oluşturmak ve korumak için kullanılabilir.
  • İleti: Message özelliği bir özel durumun nedeni hakkında ayrıntılar sağlar.
  • Kaynak: Source Özelliği, uygulamanın adına veya hataya neden olan nesneye erişmek için kullanılabilir.
  • StackTrace: özelliği, hatanın StackTrace oluştuğu yeri belirlemek için kullanılabilecek bir yığın izlemesi içerir.
  • TargetSite: TargetSite özelliği, geçerli özel durumu oluşturan yöntemi almak için kullanılabilir.

Özel durum özellikleri, temel sınıflar ve devralma ile ilgili bu incelemeden biraz bunalmış hissediyorsanız sorun değil. Endişelenmeyin, kodunuzdaki özel durumları yakalamak ve bir özel durumun özelliklerine erişmek, özel durumların ve özel durum özelliklerinin nasıl çalıştığını açıklamaktan daha kolaydır.

Uyarı

Bu modülde, uygulamanızın kullanıcı arabiriminde özel durumu bildirmek için özel durumun ileti özelliğini kullanmaya odaklanacaksınız.

Özel durum nesnesinin özelliklerine erişme

Artık özel durum nesnelerini ve bunların özelliklerini anladığınıza göre kodlamaya başlamanın zamanı geldi.

  1. Program.cs dosyanızı aşağıdaki gibi güncelleştirin:

    try
    {
        Process1();
    }
    catch
    {
        Console.WriteLine("An exception has occurred");
    }
    
    Console.WriteLine("Exit program");
    
    static void Process1()
    {
        try
        {
            WriteMessage();
        }
        catch
        {
            Console.WriteLine("Exception caught in Process1");
        }
    }
    
    static void WriteMessage()
    {
        double float1 = 3000.0;
        double float2 = 0.0;
        int number1 = 3000;
        int number2 = 0;
    
        Console.WriteLine(float1 / float2);
        Console.WriteLine(number1 / number2);
    }
    
  2. Kodu gözden geçirmek için bir dakika bekleyin.

    Bu, önceki ünitede gördüğünüz kodla aynıdır (sınama etkinliğinin çözüm kodu). WriteMessage metodunda bir özel durumun ortaya çıktığını biliyorsunuz. Process1 yönteminde özel durumun yakalandığını da biliyorsunuz. Özel durum nesnelerini ve belirli özel durum türlerini incelemek için bu kodu kullanacaksınız.

  3. Process1 yöntemini aşağıdaki gibi güncelleştirin:

    static void Process1()
    {
        try
        {
            WriteMessage();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception caught in Process1: {ex.Message}");
        }
    }
    
  4. Güncelleştirmelerinizi incelemek için bir dakikanızı alır.

    Güncellenmiş catch maddesinin, Exception adlı bir nesnedeki ex sınıfının bir örneğini yakaladığını fark edin. Yönteminizin Console.WriteLine() kullanarak nesnenin ex özelliğine eriştiğine ve hata iletisini konsolda görüntülediğine dikkat edin.

    catch yan tümcesi bağımsız değişkenler olmadan da kullanılabilir, ancak bu yaklaşım önerilmez. Bağımsız değişken belirtmezseniz, tüm özel durum türleri yakalanır ve aralarında ayrım yapamazsınız.

    Genellikle, yalnızca kodunuzun kurtarmasını yapabileceği istisnaları yakalamanız gerekir. Bu nedenle, yan tümceniz catch öğesinden System.Exceptiontüretilen bir nesne bağımsız değişkeni belirtmelidir. Özel durum türü mümkün olduğunca belirli olmalıdır. Bu, özel durum işleyicinizin çözümleyemediği özel durumların yakalanmasını önlemeye yardımcı olur. Bu alıştırmanın ilerleyen bölümlerinde belirli bir özel durum türünü yakalamak için kodunuzu güncelleştireceksiniz.

  5. Dosya menüsünde Kaydet'i seçin.

  6. Kesme noktasını aşağıdaki kod satırında ayarlayın:

    Console.WriteLine($"Exception caught in Process1: {ex.Message}");
    
  7. Çalıştır menüsünde Hata Ayıklamayı Başlat'ı seçin

    Kod yürütme kesme noktasında duraklatılmalıdır.

  8. Fare imlecini ex üzerine getir.

    IntelliSense'in daha önce incelediğiniz özel durum özelliklerinin aynısını görüntülediğine dikkat edin.

  9. Özel durum nesnesini exaçıklayan bilgileri incelemek için bir dakika bekleyin.

    Özel durumun bir System.DivideByZeroException özel durum türü olduğuna ve Message özelliğinin Attempted to divide by zero. olarak ayarlandığına dikkat edin.

    özelliğinin StackTrace hatanın oluştuğu yöntemi ve satır numarasını, hataya neden olan yöntem çağrılarının (ve satır numaralarının) sırasını raporladığına dikkat edin.

  10. Hata Ayıklama araç çubuğundaDevam'ı seçin.

  11. Konsol çıkışını incelemek için bir dakika bekleyin.

    Özel durumun Message özelliğinin uygulamanız tarafından oluşturulan çıkışa dahil olduğuna dikkat edin:

    ∞
    Exception caught in Process1: Attempted to divide by zero.
    Exit program
    

Belirli bir özel durum türünü yakalama

Artık yakalanacak özel durum türünü bildiğinize göre, yan tümcenizi catch bu özel durum türünü işleyecek şekilde güncelleştirebilirsiniz.

  1. Process1 yöntemini aşağıdaki gibi güncelleştirin:

    static void Process1()
    {
        try
        {
            WriteMessage();
        }
        catch (DivideByZeroException ex)
        {
            Console.WriteLine($"Exception caught in Process1: {ex.Message}");
        }
    }
    
  2. Kodunuzu kaydedin ve bir hata ayıklama oturumu başlatın.

  3. Güncelleştirilmiş uygulamanızın aynı iletileri konsola bildirdiğini fark edin.

    Bildirilen iletiler aynı olsa da, önemli bir fark vardır. Yönteminiz Process1 yalnızca işlemeye hazır olduğu belirli türde özel durumları yakalar.

  4. Farklı bir özel durum türü oluşturmak için yöntemini aşağıdaki gibi güncelleştirin WriteMessage :

    static void WriteMessage()
    {
        double float1 = 3000.0;
        double float2 = 0.0;
        int number1 = 3000;
        int number2 = 0;
        byte smallNumber;
    
        Console.WriteLine(float1 / float2);
        // Console.WriteLine(number1 / number2);
        checked
        {
            smallNumber = (byte)number1;
        }
    }
    
  5. checked ifadesinin kullanımına dikkat edin.

    Bir tamsayı türünün değerini farklı bir tamsayı türüne atayan tamsayı türü hesaplamaları yapılırken, sonuç taşma denetimi bağlamına bağlıdır. Bir checked bağlamda, kaynak değer hedef türün aralığı içindeyse dönüştürme başarılı olur. Aksi takdirde, bir OverflowException atılır. İşaretlenmemiş bir bağlamda dönüştürme her zaman başarılı olur ve aşağıdaki gibi devam eder:

    • Kaynak türü hedef türden büyükse, kaynak değeri "ek" en önemli bitleri atılarak kesilir. Sonuç daha sonra hedef türün değeri olarak değerlendirilir.

    • Kaynak türü hedef türden küçükse, kaynak değer, hedef türle aynı boyuta ulaşması için ya işaret genişletilir ya da sıfır genişletilir. Kaynak türü imzalıysa, işaret genişletmesi kullanılır; kaynak türü işaretsizse sıfır genişletmesi kullanılır. Sonuç daha sonra hedef türün değeri olarak değerlendirilir.

    • Kaynak türü hedef türle aynı boyuttaysa, kaynak değer hedef türün değeri olarak değerlendirilir.

    Uyarı

    Kod checked bloğunun içinde olmayan tam sayı türü hesaplamaları, bir unchecked kod bloğunun içinde gibi değerlendirilir.

  6. Kodunuzu kaydedin ve bir hata ayıklama oturumu başlatın.

  7. Yeni bir özel durum türünün en üst düzey ifadelerde catch yan tümcesi tarafından, yöntemin içinde Process1 değil, yakalandığını görebilirsiniz.

    Uygulamanız konsola aşağıdaki iletileri yazdırır:

    ∞
    An exception has occurred
    Exit program
    

    Uyarı

    catch içindeki Process1 blok yürütülmedi. İstediğiniz davranış budur. Yalnızca kodunuzun işlemeye hazır olduğu özel durumları yakalayın.

Kod bloğunda birden çok istisnayı yakalama

Bu noktada, tek bir kod bloğunda birden çok özel durum oluştuğunda ne olacağını merak ediyor olabilirsiniz. Kodunuz, her istisna oluştuğunda catch işlemi yapacak mı?

  1. WriteMessage yöntemini aşağıdaki gibi güncelleştirin:

    static void WriteMessage()
    {
        double float1 = 3000.0;
        double float2 = 0.0;
        int number1 = 3000;
        int number2 = 0;
        byte smallNumber;
    
        Console.WriteLine(float1 / float2);
        Console.WriteLine(number1 / number2);
        checked
        {
            smallNumber = (byte)number1;
        }
    }
    
  2. Aşağıdaki kod satırında yönteminin WriteMessage() içinde kesme noktası ayarlayın:

    Console.WriteLine(float1 / float2);
    
  3. Kodunuzu kaydedin ve bir hata ayıklama oturumu başlatın.

  4. Kodunuzda her seferinde bir satır ilerleyin ve kodunuz ilk özel durumu işledikten sonra ne olacağına dikkat edin.

    İlk özel durum oluştuğunda, denetim özel durumu işleyebilen ilk catch yan tümceye geçirilir. İkinci özel durumu oluşturacak koda hiçbir zaman ulaşılamazdı. Bu, kodunuzun bir bölümünün hiçbir zaman yürütülmeyeceğini gösterir. Bu durum ciddi sorunlara yol açabilir.

  5. Birden çok özel durumu nasıl yönetebildiğinizi ve kodunuzun birden çok özel durumu ne zaman/neden yönetmesini istemediğinizi düşünmek için bir dakikanızı alır.

    Bu modülün önceki bölümlerinde özel durumların mümkün olduğunca yakın bir yerde yakalanması gerektiğini öğrendiniz. Bunu göz önünde bulundurarak, kendi WriteMessage kullanarak istisnaları yakalamak için yöntemi güncelleştirmeyi try-catch seçebilirsiniz. Örneğin:

    static void WriteMessage()
    {
        double float1 = 3000.0;
        double float2 = 0.0;
        int number1 = 3000;
        int number2 = 0;
        byte smallNumber;
    
        try
        {
            Console.WriteLine(float1 / float2);
            Console.WriteLine(number1 / number2);
        }
        catch (DivideByZeroException ex)
        {
            Console.WriteLine($"Exception caught in WriteMessage: {ex.Message}");
        }
        checked
        {
            smallNumber = (byte)number1;
        }
    }
    

    Ayrıca, OverflowException yöntemi içinde try-catch'a neden olan kodu ayrı bir WriteMessage() içinde de sarmalayabilirsiniz.

    checked
    {
        try
        {
            smallNumber = (byte)number1;
        }
        catch (OverflowException ex)
        {
            Console.WriteLine($"Exception caught in WriteMessage: {ex.Message}");
        }  
    }
    
  6. Hangi koşullar altında ardışık istisnaları yakalamak istenmeyen bir durum olabilir?

    Yönteminizin (veya kod bloğunun) iki parçalı işlemi tamamlarken olduğu durumu göz önünde bulundurun. İşlemin ikinci bölümünün, ilk bölümün tamamlanmasına bağlı olduğunu varsayalım. İşlemin ilk bölümü başarıyla tamamlanamıyorsa, işlemin ikinci bölümüne devam etmek için bir neden yoktur. Bu durumda, daha büyük işlemin kalan bölümünü veya bölümlerini denemeden kullanıcıya hata durumunu açıklayan bir ileti sunmak genellikle daha iyidir.

Kod bloğunda ayrı özel durum türlerini yakalama

Verilerinizdeki varyasyonların farklı özel durum türlerine neden olabileceği zamanlar vardır.

  1. Kesme noktalarınızı temizleyin ve Program.cs dosyanızın içeriğini aşağıdaki kodla değiştirin:

    // inputValues is used to store numeric values entered by a user
    string[] inputValues = new string[]{"three", "9999999999", "0", "2" };
    
    foreach (string inputValue in inputValues)
    {
        int numValue = 0;
        try
        {
            numValue = int.Parse(inputValue);
        }
        catch (FormatException)
        {
            Console.WriteLine("Invalid readResult. Please enter a valid number.");
        }
        catch (OverflowException)
        {
            Console.WriteLine("The number you entered is too large or too small.");
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    
  2. Bu kodu gözden geçirmek için bir dakika bekleyin.

    İlk olarak, kod adlı inputValuesbir dize dizisi oluşturur. Dizideki veriler, sayısal değerler girmesi istenen bir kullanıcı tarafından girilen giriş değerlerini temsil etmeye yöneliktir. Girilen değere bağlı olarak, farklı özel durum türleri oluşabilir.

    Kodun "input" dize değerlerini tamsayılara dönüştürmek için yöntemini kullandığına int.Parse dikkat edin. Kod int.Parse bir try kod bloğunun içine yerleştirilir.

  3. Aşağıdaki kod satırında bir kesme noktası ayarlayın:

    int numValue = 0;
    
  4. Kodunuzu kaydedin ve bir hata ayıklama oturumu başlatın.

  5. Kodda her seferinde bir satır ilerleyin ve farklı özel durum türlerinin yakalandığını fark edin.

Özet

Bu ünitede hatırlamanız gereken birkaç önemli şey şunlardır:

  • Belirli bir özel durum türünü yakalayacak şekilde catch cümlesi yapılandırılmalıdır. Örneğin, DivideByZeroException özel durum türü.
  • Bir özel durum nesnesinin özelliklerine blok içinde catch erişilebilir. Örneğin, uygulama kullanıcısını Message bir sorun hakkında bilgilendirmek için özelliğini kullanabilirsiniz.
  • Birden fazla catch özel durum türünü yakalamanız gerektiğinde iki veya daha fazla yan tümce belirtebilirsiniz.