Ana içeriğe atla

( 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)
{
    //
}

Yorumlar

Bu blogdaki popüler yayınlar

Linux En Az Sistem Gereksinimi İsteyen Dağıtımları Değerlendirilmesi

Linux İşletim Sisteminin Dağıtımlarının En az sistem gereksinimi isteyen sürümleri, değerlendirilmesi aşağıdadır, Değerlendirilen dağıtımlar şunlardır: Ubuntu Xubuntu Lubuntu Damn Small Linux Linux Mint Fedora Opensuse Debian Rat Hat Suse Linux Suse Linux Sistem Gereksinimleri: Pentium 1-4 ya da Xeon; AMD Duron, Athlon (XP, MP ya da 64), Sempron ya da Opteron 256MB RAM 500MB boş disk alanı 800x600 yada üstü resolution Rat Hat Memory Gerekli: 4 GB of memory Önerilen: 8 GB of memory CPU Gerekli: Intel Core processor, 2.4GHz, 512K cache or equivalent Önerilen: Intel multi-core processor, 2.4GHz dual processor, 512K cache or equivalent Storage 5 GB alan temel kurulum için. 40 GB alan Channel başına. 10 GB alan Cache dizini için(/var/cache/rhn) Disk yapılandırması olarak Raid 5 tavsiye edilir. Database İlk kurulum için 12 GB alan önerilir. Client ve channel hesaplamaları ise, 250 KB alan client system başına, 500 KB alan çhannel başına, ayrıca 230 KB channel da

( C#) Ders 4 - Diziler, Çok Boyutlu Diziler, Düzenli ve Düzensiz Çok Boyutlu Diziler Nasil Kullanilir. foreach Döngüsünün Kullanimi.

C# da Diziler Diziler için ayni tipteki verilerin tutuldugu bir koleksiyon diyebiliriz. Örnegin integer verinin bir yigin seklinde tutulmasi için dizileri kullaniriz. C# da diziler referans tipinde degiskenlerdendir. C# da tanimlanan tüm diziler System.Array sinifindan türemis bir nesnedir. C# da diziler asagidaki gibi tanimlanir. ? 1 <veri tipi>[] <degisken ismi> = new <veri tipi>[<dizinin boyutu>]; 10 adet integer veri tutan bir dizinin tanim ise ? 1 int [] integerDizi = new int [10]; Bir dizinin boyutlari sabittir ve kullanilmadan önce belirlenmelidir. Dizi boyutunu belirlemek için baska bir degiskende kullanabilirsiniz. ? 1 2 int boyut = 10; int [] integerDizi = new int [boyut]; Diziyi tanimlama ve baslangiç degerlerini atama islemini ayri satirlardada yapabilirsiniz. ? 1 2 int [] integerDizi; integerDizi = new int [10]; Ayrica dizileri tanimlarken, dizi içine atmak istedigin

JavaScript ile Popup Pencereleri

Popup pencereleri bir sayfa içinde ek bir pencere açma islemidir. Popup pencereler JavaScript kullanarak açilirlar. Popup pencereler yaygin olarak reklam göstermek amaciyla kullanilir. Diger bir kullanim amaci ise yardim sayfalari tasarlamak içindir. Ihtiyaciniz dogrultusunda farkli amaçlar için kullanilabilirler. Popup pencereler; Sayfa yüklenmesinde,Sayfadan çikildiginda,Kullanici bir linki tikladiginda açilabilir. Sayfa yüklenirken veya kapatilirken bir popup açmak için body etiketi içine asagidaki kodu yazmaniz yeterlidir. Sayfa yüklenirken ? 1 <body onload= "javascript: alert(Load islemi!')" > Sayfa Kapatilirken ? 1 <body onunload= "javascript: alert('UnLoad islemi!')" Link tiklandiginda ? 1 <a href= "javascript: alert('link Tiklandi!')" >Popup Aç!</a> Popup olarak yeni bir pencere açmak istiyorsak window.open() metodunu kullaniriz. Window.open metodun