CodeGym /Kurslar /C# SELF /İstisnalarla tanışlıq və onların iyerarxiyası

İstisnalarla tanışlıq və onların iyerarxiyası

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Təsəvvür elə, iki ədədin bölünməsi üçün kalkulyator yazırsan. Hər şey əladır, ta ki kimsə sıfıra bölmək istəməyənə qədər:

int a = 10;
int b = 0;
int result = a / b; // Boom!
Sıfıra bölmə istisna yaradır

Bu anda proqram "çökür" və istifadəçi qorxulu error mesajı görür. Bax bu istisna vəziyyəti adlanır — proqramın "normal" işləmə ssenarisində baş verməməli olan və xüsusi diqqət tələb edən hadisədir.

İstisna — bu xüsusi bir mexanizmdir ki, .NET proqramına nəsə qeyri-adi baş verdiyini bildirir və icra dayandırılmalı ya da xüsusi qaydada işlənməlidir.

Əgər icra zamanı error baş verirsə (məsələn, sıfıra bölmə, mövcud olmayan fayla müraciət, ya da — köhnə tanışımız — null-un dereferens edilməsi), .NET xüsusi istisna obyektini "atır" (throw). Bu zaman uyğun handler axtarılır ki, həmin vəziyyəti "tutsun" (catch) və necə reaksiya verəcəyini bilsin.

Niyə "error kodu" qaytarmayaq?

Error kodu qaytarmaq olardı — bir çox köhnə dillər (Pascal, C və hətta bəzi müasir API-lər) belə edir. Amma bu rahat deyil və təhlükəlidir: error kodunu yoxlamağı asanlıqla unutmaq olar (axı hamımız yaxşıya ümid edirik) — və harda səhv getdiyini tapmaq çox çətindir. İstisnalar isə istənilən error-u mərkəzləşdirilmiş şəkildə izləməyə və onlara çevik reaksiya verməyə imkan verir, əsas kodu yoxlamalarla doldurmadan.

2. İstisnanın "atılması"

İstisnalar avtomatik baş verə bilər — runtime error zamanı, ya da əl ilə throw açar sözü ilə atıla bilər:


int[] arr = new int[2];
arr[10] = 5; // istisna özü atılacaq System.IndexOutOfRangeException

throw new Exception("Tam fəlakət!"); // Exception istisnasını əl ilə atırıq

Hətta sənə elə gələ bilər ki, proqramın ideal dizayn olunub, amma həmişə nəsə gözlənilməz baş verə bilər: istifadəçi faylı bağladı, internet getdi, kimsə kompüteri söndürdü (demək olar ki).

Şükür ki, .NET bizə təkcə istisna "atmaq" yox, həm də onları tutub işləmək üçün vasitələr verib — onlara bir azdan baxacağıq.

3. İstisnanın həyat dövrü: throw-dan catch-ə qədər

Kodda nəsə pis baş verəndə, .NET "təcili prosedur" işə salır:

  1. İstisna obyektini yaradır (məsələn, IndexOutOfRangeException).
  2. Onu atır throw açar sözü ilə.
  3. Handler axtarır: call stack-i aşağıdan yuxarıya baxır (cari metoddan çağırana doğru) — atılmış istisnanın tipinə uyğun ilk catch blokunu axtarır.
  4. Əgər handler tapıldısa — proqram catch blokunun içində davam edir.
  5. Əgər heç bir handler tapılmadısa — proqram qəza ilə bağlanır və error detalları ilə "call stack" çıxarır.

Bu, sanki topun pilləkənlərlə gərgin uçuşuna bənzəyir — ta ki, qəbul edənə çatana qədər stack-də "tullanır".

4. .NET-də istisnaların iyerarxiyası

"Ata və övladlar" ağacı

.NET-də (əksər OOP dillərində olduğu kimi) istisnalar bir-birindən miras alan siniflər şəklində qurulub və bütöv bir iyerarxiya yaradır.

Onların hamısının ortaq əcdadı — əsas System.Exception sinifidir.


System.Object
    └─ System.Exception
         ├─ System.SystemException
         │     ├─ System.NullReferenceException
         │     ├─ System.IndexOutOfRangeException
         │     ├─ System.DivideByZeroException
         │     ├─ System.OutOfMemoryException
         │     └─ ... və bir çox başqaları
         ├─ System.IO.IOException
         │     ├─ System.IO.FileNotFoundException
         │     ├─ System.IO.DirectoryNotFoundException
         │     └─ ...
         ├─ System.ArgumentException
         │     ├─ System.ArgumentNullException
         │     └─ System.ArgumentOutOfRangeException
         └─ (öz Exception siniflərin)
.NET-də istisnaların sxematik iyerarxiyası

Niyə siniflər?

Sinif iyerarxiyası sayəsində bir anda bütöv bir "problem sinifini" tuta bilərsən — məsələn, funksiyaların argumentləri ilə bağlı bütün error-ları (ArgumentException və onun törəmələri). Həm də, bu, öz error tiplərini əlavə etməyə imkan verir (bunun haqqında növbəti dərslərdə danışacağıq).

Ən məşhur .NET istisnaları

  • NullReferenceException — obyektin metodu və ya property-sinə müraciət cəhdi, amma obyekt null-dır. Köhnə dost!
  • DivideByZeroException — sıfıra bölmə.
  • IndexOutOfRangeException — massiv sərhədlərindən kənara çıxma.
  • ArgumentException, ArgumentNullException, ArgumentOutOfRangeException — metod parametrlərində səhvlər.
  • FileNotFoundException, IOException — fayllarla işləyərkən problemlər.
  • InvalidOperationException — obyektin cari vəziyyətində əməliyyat mümkün deyil.
  • FormatException — data formatı səhvdir (məsələn, "abcd"-ni ədədə çevirmək cəhdi).

5. Nümunələr: müxtəlif istisnalar necə "partlayır"

Gəlin aydın olsun deyə, müxtəlif istisnaları yaradan kod nümunələrinə baxaq.

Nümunə 1: NullReferenceException

string? str = null;
Console.WriteLine(str.Length); // Burda "Boom!" — str null-dır

Çıxış:

Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.

Nümunə 2: DivideByZeroException

int a = 42;
int b = 0;
int c = a / b; // Təhlükəli! Sıfıra bölmə

Çıxış:

Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.

Nümunə 3: IndexOutOfRangeException

int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[5]); // 5 indeksli element yoxdur

Burada artıq əlavə indeks var və çıxış belədir:

Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.

Nümunə 4: FileNotFoundException

using System.IO;

string content = File.ReadAllText("secret.txt");

Əgər "secret.txt" adlı fayl yoxdursa, təxminən belə mesaj alacaqsan:

Unhandled exception. System.IO.FileNotFoundException: Could not find file '/Users/zapp/RiderProjects/ConsoleApp1/ConsoleApp1/bin/Debug/net9.0/secret.txt'.

Nümunə 5: FormatException

string input = "on üç";
int number = int.Parse(input); // Sətir ədəd deyil

Çıxış:

Unhandled exception. System.FormatException: The input string 'on üç' was not in a correct format.

6. Bu bilikləri necə istifadə etməli?

İstisnaların necə işlədiyini başa düşmək hər bir developer üçün həqiqətən vacibdir. Bu sadəcə "teoriya üçün nəzəriyyə" deyil, proqramlarının stabilliyinə birbaşa təsir edən praktik bacarıqdır. Sən error-ları düzgün işləməyi biləndə, proqramın ilk səhvdə "çökməyəcək", əksinə — istifadəçiyə nə baş verdiyini aydın və sakit şəkildə bildirəcək. Bu onu daha etibarlı, peşəkar və sadəcə insanlara daha dost edir.

Və bu təkcə rahatlıq üçün deyil. Müsahibələrdə tez-tez istisna işləmə mexanizmi, Exception tipləri və ümumiyyətlə .NET-də bu mexanizmin necə işlədiyi barədə suallar verirlər. Yəni mövzunu yaxşı başa düşmək — iş tapanda da əlavə üstünlükdür.

Üstəlik, real layihələrdə istisnalarla hələ çox rastlaşacaqsan. Fayllarla, şəbəkə ilə, verilənlər bazası ilə, üçüncü tərəf kitabxanaları və framework-lərlə işləmək — bunların hamısı istisna sistemindən aktiv istifadə edir. Ona görə də, yaxşı olar ki, əvvəlcədən başa düşəsən necə işləyir, sonra sürpriz olmasın.

7. İstisnalarla işləyərkən tipik səhvlər

Səhv №1: istisnaları ümumiyyətlə görməməzlikdən gəlmək.
Bəzi yeni başlayanlar (bəzən də təcrübəli developer-lər) istisnaları nəsə zərərli və ya maneə kimi qəbul edirlər. Ya onları tamamilə görməməzlikdən gəlirlər, ya da daha pis — kodu catch { } ilə bürüyüb heç nə etmirlər. Nəticədə proqram "sakitcə" qəribə vəziyyətdə işləməyə davam edir və problemin səbəbini tapmaq mümkün olmur.

Səhv №2: istisnalarla adi error-ları qarışdırmaq.
Tez-tez unudurlar ki, hər error-u try-catch ilə tutmaq lazım deyil. Məsələn, istifadəçi səhv data daxil edibsə, əvvəlcə onu əl ilə yoxlamaq daha yaxşıdır, nəinki FormatException-a ümid etmək və ya istisnalardan məntiq mexanizmi kimi istifadə etmək. İstisnalar — istisna hallar üçündür, rutin üçün yox.

Səhv №3: istisna iyerarxiyasını düzgün başa düşməmək.
Bəzən çox ümumi sinifi (Exception) tutmağa çalışırlar və nəticədə hər şeyi tuturlar, o cümlədən heç işləməməli olan error-ları. Bəzən isə əksinə — çox dar tipləri (IndexOutOfRangeException, NullReferenceException) tuturlar, amma başqa istisnaların da ola biləcəyini unudurlar. Əsas odur ki, .NET-də istisna iyerarxiyasının necə qurulduğunu və nəyin işlənməsini istədiyini başa düşəsən.

Və ən əsası — yadında saxla: C#-da istisnalar — bu nə qəza, nə də "hər şey bitti" siqnalıdır, sadəcə xüsusi icra ssenarisinə keçid mexanizmidir. Düzgün istifadə etsən, bu güclü alətdir.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION