Yazilim Mutfagi Dersleri ( C#) Ders 6 – Hata Yakalama ( Exception Handling) Mekanizmasi

Hata Yakalama (Exception Handling)

Bu dersimizde C# da Exception(hata) mekanizmasini ögrenecegiz. Farkli exceptionlari nasil yakalayacagimiz üzerinde duracagiz. Sonraki dersimizde ise kendi exceptionlarimizi nasil üretecegimizi ögrenecegiz.

Basit ifade ile .NET de hata yakalama, run-time aninda olusan ve programimizi sonlandiracak olan hatalari yakalamamizi saglayan bir mekanizmadir.

Basit bir kodla ilk hatamizi anlamaya çalisalim.

static void Main(string[] args)

{

    string metin = "yazilimmutfagi";

    int i = 5;

    Console.WriteLine(metin[i]);

}


Yukarida verilen örnek de. Main fonksiyonu içinde metin diye bir string olusturdum ve bu stringin 5. Karakterini ekrana bastik. Ekran çiktisi asagidaki gibi oldu.

i

Devam etmek için bir tusa basin . . .


Peki, Main içindeki kodu asagidaki gibi degistirirsek?

    string metin = "yazilimmutfagi";

    int i = 15;

    Console.WriteLine(metin[i]);


Yukaridaki kod derleme aninda hata vermeyecek. Yukaridaki degisikligi yapip programimi çalistirdigimizda ne olacak? Metin stringine ait toplam 14 karakter var ve son karakterin indexi 13 olduguna göre ve bizde 15. indexdeki karakteri almak istedigimize göre çalisma aninda asagidaki hatayi alacagiz.

Islenmeyen Özel Durum: System.IndexOutOfRangeException: Dizin, dizi sinirlarinin

 disindaydi.

   konum: yzDersler.Program.Main(String[] args) D:\TTCodeland\deneme\WindowsForm

sApplication2\yzDersler\Program.cs içinde: satir 13

 

Simdi gelelim bu hatayi nasil engelleyecegimize.

Ilk olarak kullandigimiz index degiskeninin metinin uzunlugundan daha fazla olup olmadigini kontrol etmeliyiz. Main fonksiyonunu asagidaki gibi degistirirseniz i degiskenine verdiginiz yanlis bir deger programinizin çökmesini engeller.

static void Main(string[] args)

{

    string metin = "yazilimmutfagi";

    int i = 14;

    if (i >= metin.Length || i<0)

        Console.WriteLine("hatali giris");

    else

        Console.WriteLine(metin[i]);

}

 

Yukaridaki düzenleme ile indexin metne ait uzunluktan büyük esit ve 0 dan küçük olmasi durumunda ekrana hata mesaji yaziyoruz, böylece çalisma aninda programimizin çökmesini engellemis oluyoruz.

.NET ve C# da Hatalar

Yukarida verdigimiz örnek dikkat ederseniz beklenen bir hatadir. Peki, beklenmeyen hatalar olustugunda ne yapabiliriz. Adi üstünde beklenmeyen hata yani bunun için yukaridaki gibi bir tedbir almamiz mümkün degil. Bu durumda .NET’in hata yakalama mekanizmasi devreye giriyor.

Hatalar ile ilgili bazi önelmi noktalar:

.NET de tüm hatalar birer nesnedir. NET olusan tüm hatalar System.Exception sinifindan türemistir. Kodda olusan bir hatayi kodu try…catch bloklari arasina alarak yakalayabiliriz.

Hata olusacak olan kodu try blogu içine aliriz. Try blogundan sonra olusturacagimiz bir catch blogu ile olusan hatayi yakalar ve isleriz. Birden farkli catch blogu kullanarak hatanin tipine göre farkli islemler yaptirabiliriz.

Hata olussa da olusmasa da çalistirmak istedigimiz bir kod varsa bunun try..catch bloklari sonuna ekleyecegimiz bir finally blogu içinde yapariz. Finally blogunu eklemek istege baglidir.

Eger sizin yakalayamadiginiz bir hata olusursa .NET CLR bunu yakalar ve programinizin sonlanmasina sebep olur

Try…catch…finally bloklarini kullanarak hatalari yakalamak

Try…catch blogu

string s = null;

try

{

    Console.WriteLine("try blogu içinde.. s.ToLower() çalismadan hemen önce");

    Console.WriteLine(s.ToLower());

    Console.WriteLine("try blogu içinde.. s.ToLower() çalisdiktan sonra");

 

 

}

catch (NullReferenceException e)

{

    Console.WriteLine("catch blogunda");

    Console.WriteLine("NullReferenceException hatasi yakalandi");

}

Console.WriteLine("try.. catch blogu çalistiktan sonra");



try blogu içinde.. s.ToLower() çalismadan hemen önce

catch blogunda

NullReferenceException hatasi yakalandi

try.. catch blogu çalistiktan sonra

 

Yukaridaki örnegi incelerseniz null deger atanmis s degiskeni içinde bulunan karakterleri küçük harf yapamaya çalisiyoruz. S degiskeni null oldugu içinde NullReferenceException hatasi olusuyor. Bu hata s.ToLower() kisminda olustugu için bu satirdan sonra try blogundaki kodlar çalismadan catch bloguna geçiyor.  Peki örnekteki s degiskenine bir string deger oalrak YAZILIMMUTFAGI verelim(string s = "YAZILIMMUTFAGI";).Bu durumda yukaridaki kodda bir hata olusmayacak ve catch blogunda yazdigimiz kodlar çalismayacaktir. Bu atamayi yaptigimizda ekran çiktisi asagidaki gibi olur.

try blogu içinde.. s.ToLower() çalismadan hemen önce

yazilimmutfagi

try blogu içinde.. s.ToLower() çalisdiktan sonra

try.. catch blogu çalistiktan sonra


catch blogu içinde olusan hata nesnesi bir hata mesaji ve hatanin nerden kaynaklandigini tutar. Bunu yapabilmek için yukaridaki örnegimizi biraz degistirelim.

string s = null;

try

{

    Console.WriteLine("try blogu içinde.. s.ToLower() çalismadan hemen önce");

    Console.WriteLine(s.ToLower());

    Console.WriteLine("try blogu içinde.. s.ToLower() çalisdiktan sonra");

 

 

}

catch (NullReferenceException e)

{

    Console.WriteLine("catch blogunda");

    Console.WriteLine("NullReferenceException hatasi yakalandi");

    Console.WriteLine("\nHata Mesaji");

    Console.WriteLine("================");

    Console.WriteLine(e.Message);

    Console.WriteLine("\nHatanin olustugu kisim:");

    Console.WriteLine(e.StackTrace);

}

Console.WriteLine("try.. catch blogu çalistiktan sonra");


Ekran Çiktisi:
.

try blogu içinde.. s.ToLower() çalismadan hemen önce

catch blogunda

NullReferenceException hatasi yakalandi

 

Hata Mesaji

================

Nesne basvurusu bir nesnenin örnegine ayarlanmadi.

 

Hatanin olustugu kisim:

   konum: yzDersler.Program.Main(String[] args) D:\TTCodeland\deneme\WindowsForm

sApplication2\yzDersler\Program.cs içinde: satir 17

try.. catch blogu çalistiktan sonra

 

Finally Blogu

Finally blogu Try catch blogundan hemen sonra tanimlanir. Kullanilmasi istege baglidir. Try blogu içinde hata olsa da olmasa da finally blogu içine yazilan kodlar çalisir. Finall blogu genellikle bazi kaynaklari serbest birakmak için kullanilir. Örnegin try blogunda bir dosya açtiniz, eger bir hata olusursa try blogu içinde dosyayi kapatma kodu çalismadan catche atlar ve sonuçta dosyaniz kapanmaz.  Bu durumda siz dosya kapatma islemini finally blogunda yapacak olursaniz her halükarda dosyanizin kapanmasini garanti altina almis olursunuz. Bu bir dosya degilde bir veritbani baglantisi veya tcp socket olabilir.

Yukarida yaptigimiz son örnege bir finally blogu ekleyerek hata olusmasi veya olusmamasi durumunda kodumuzun nasil çalistigini inceleyelim.

string s =  "YAZILIMMUTFAGI";

try

{

    Console.WriteLine("try blogu içinde.. s.ToLower() çalismadan hemen önce");

    Console.WriteLine(s.ToLower());

    Console.WriteLine("try blogu içinde.. s.ToLower() çalisdiktan sonra");

 

 

}

catch (NullReferenceException e)

{

    Console.WriteLine("catch blogunda");

    Console.WriteLine("NullReferenceException hatasi yakalandi");

    Console.WriteLine("\nHata Mesaji");

    Console.WriteLine("================");

    Console.WriteLine(e.Message);

    Console.WriteLine("\nHatanin olustugu kisim:");

    Console.WriteLine("================");

    Console.WriteLine(e.StackTrace);

}

finally

{

    Console.WriteLine("finally blogu");

}


Ekran Çiktisi:

try blogu içinde.. s.ToLower() çalismadan hemen önce

yazilimmutfagi

try blogu içinde.. s.ToLower() çalisdiktan sonra

finally blogu

Devam etmek için bir tusa basin . . .

 

Simdide programi hataya düsürüp finally blogunun nasil davrandigini gözleyelim. Yukaridaki kodda Main fonksiyonu içinde s degiskenine null degeri verelim (string s =  null;). Bu durumda



try blogu içinde.. s.ToLower() çalismadan hemen önce

catch blogunda

NullReferenceException hatasi yakalandi

 

Hata Mesaji

================

Nesne basvurusu bir nesnenin örnegine ayarlanmadi.

 

Hatanin olustugu kisim:

================

   konum: yzDersler.Program.Main(String[] args) D:\TTCodeland\deneme\WindowsForm

sApplication2\yzDersler\Program.cs içinde: satir 17

finally blogu

 

Iki ekran çiktisina da bakacak olursaniz finally blogunun çalistigini her seferinde çalistigini görürsünüz.

Birden Çok Catch Blogu Kullanarak Çoklu Hata Yakalama

Birden fazla catch kullanarak try blogu içinde olusan birden fazla, birbirinden farkli hata türlerini yakalayabilirsiniz. Mesela üç adet cetch kullanalim 1. NullReferrenceException 2. De IndexOutOfRangeException ve 3. Sünde ise diger herhangi bir hata yakalayalim. IndexOutOfRangeException hata türü bir dizinin eleman sayisindan büyük veya 0 dan küçük olan elemanlarina erismeye çalistiginiz zaman olusur.

string s = "Sabri";

int[] i = new int[3];

try

{

    Console.WriteLine("Try Blogu içine giriyor.");

   

    //NullReferenceException hatasi  verebilicek kisim

    Console.WriteLine("Kucuk harflere çevrilmis hali : "+s.ToLower());

 

    //NullReferenceException veya IndexOutOfRangeException hatasi  verebilicek kisim

    Console.WriteLine("Dizinin ilk elemani :"+i[0].ToString());

 

    //DivideByZeroException hatasi verebilecek kisim

    i[0] = 1;

    i[1] = 4 / i[0];

    Console.WriteLine("Try Blogu Bitti");

}

catch (NullReferenceException e)

{

    Console.WriteLine("NullReferenceException hatasi yakalandi..");

}

catch (IndexOutOfRangeException e)

{

    Console.WriteLine("IndexOutOfRangeException hatasi yakalandi..");

}

catch (Exception e)

{

    Console.WriteLine("Hatasi yakalandi..");

    Console.WriteLine(e.Message);

}

 

Ekran çiktisi:

Try Blogu içine giriyor.

Kucuk harflere çevrilmis hali : sabri

Dizinin ilk elemani :0

Try Blogu Bitti

 

Yukaridaki örnekte s degiskenine null deger verin ve sonucu izleyin daha sonra i dizisinin ilk elemanini 0 yapin ve sonucu izleyin.  Ayrica dizinin ilk elemanini buldugumu yere dizi boyutlarindan büyük veya 0 dan küçük bir sayi girip sonucu izleyin.

 

Birden fazla catch blogu kullandigimiz zaman eger hata olusursa catch bloklari sirasi ile degerlendirilir, olusan hata ilk hangi bloga uyuyorsa o blok çalisir ve gerisi çalismaz. Yani bir NullReferenceException yakalayacaksak bu catch blogundan önce daha genel bir hata yakalamaya kodu olmamalidir. Kisacasi hata yakalamak için kullandigimiz catch bloklarindaki hata türleri özelden genele dogru gitmelidir. En basta Exception sinifindan türeyen bir hata yakalamaya kalkarsak, tüm hatalar bu siniftan türedigi için ilk catch blogu çalisacak ve digerleri çalismayacaktir. Örnegin asagidaki gibi bir yapi kurarsak tüm hatalar birinci catch tarafindan yakalanir çünkü NullReferenceException da IndexOutOfRangeException da Exception sinifindan türemistir ve daha özel kullanim içindir.

try

{

   //

}

catch (Exception e)

{

    //

}

catch (NullReferenceException e)

{

    //

}

catch (IndexOutOfRangeException e)

{

    //

}

 

Bu dersin sonuna geldik. Bir sonraki derste Kendi hata türlerimizi nasil olusturacagimizi ögrenecegiz. Bu konu ile ilgili sorularini forum üzerinde açilan Exception konusu altina sorabilirsiniz.
.

 

 

 

 

 

 

Tags:

7 thoughts on “Yazilim Mutfagi Dersleri ( C#) Ders 6 – Hata Yakalama ( Exception Handling) Mekanizmasi

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.