İstisnai Durum Yönetimi başlıklı yazımızda Try-Catch-Finaly blokları ile uygulamamızda meydana gelen hataları nasıl yakalayacağımıza ve türlerine göre nasıl filtreleyebileceğimize değinmiştik. Bu yazımızda ise; kendi Exception sınıflarımızı nasıl oluşturacağımıza ve hangi amaçlar doğrultusunda kullanabileceğimize değineceğiz.
Hazır Exception Sınıfları
.NET Framework içerisinde bir çok hazır Exception sınıfı bulunmaktadır. Uygulamamızda çalışma anında bir hata meydana geldiğinde .Net, hatanın türüne göre ilgili Exception sınıfından bir nesne oluşturarak geriye fırlatmaktadır.
class Program { static void Main(string[] args) { int sayi_1 = 18; int sayi_2 = 0; try { int sonuc = sayi_1 / sayi_2; } catch(Exception ex) { Console.WriteLine("Hata Mesajı:{0}", ex.Message); } } }
Yukarıdaki örneği inceleyecek olursak; Bir sayının sıfıra bölümü sonsuz olduğundan, sayi_1 değişkeni sayi_2 değişkenine bölünmek istendiğinde .Net bir Exception nesnesi fırlatacaktır. Bize düşen ise try-catch blokları ile bu hatayı yakalamaktır. Yukarıdaki uygulama çalıştırıldığı takdirde ekran çıktısı aşağıdaki gibi olacaktır;
Hata Mesajı:Sıfırla bölme girişiminde bulunuldu. Press any key to continue . . .
Ekran çıktısını inceleyecek olursak; .Net’in sadece hata vermekle kalmadığını, hatanın neden oluştuğuna dair bilgide verdiğini görebiliriz. Tıpkı bu örnekte olduğu gibi, bizlerde hatalı işlem yapılmasını önlemek amacıyla kontrollü bir şekilde Exception’lar fırlatabiliriz.
Kendi Exception Sınıflarımızı Nasıl Oluşturabiliriz ?
Exception sınıflarının nasıl oluşturulduğunu ve kullanıldığını örnek bir senaryo üzerinden ilerleyerek anlamaya çalışalım. Kullanıcıların şifrelerini değiştirebileceği bir metot yazmak istediğimizde, metot içerisinde en basit haliyle aşağıdaki kontrolleri yapabiliriz;
- Belirtilen kullanıcı adı sistemimizde var mı? Eğer yoksa olmayan bir kullanıcının şifresi değiştirilmek isteniyor demektir, böylesi bir durumda bir hata mesajı fırlatmamız gerekir.
- Şifresini değiştirmek isteyen kullanıcıdan, doğrulama amaçlı eski şifresini girmesini istediğimizde yanlış bir şifre girerse bir hata mesajı döndürmemiz gerekir.
Yukarıdaki iki durumu da dikkate alarak Exception sınıflarımızı oluşturalım;
class UserNotFoundException : Exception { public UserNotFoundException() : base("Kullanıcı Adı Hatalı!") { } } class WrongPasswordException : Exception { public WrongPasswordException() : base("Hatalı Şifre!") { } }
Kullanıcı sistemimize kayıtlı olmadığı durumda fırlatacağımız UserNotFoundException ve yanlış şifre girildiği zaman fırlatacağımız WrongPasswordException sınıflarımızı oluşturduk. Dikkat edilecek olursa her iki sınıfımızda Exception sınıfından türetilmiştir ve base anahtar sözcüğü ile hata mesajları temel sınıf olan Exception sınıfının yapıcı metoduna parametre olarak gönderilmiştir.
Oluşturacağımız Exception sınıfları, “Exception” sınıfından türetilmelidir.
base anahtar sözcüğünün kullanımı hakkında daha detaylı bilgi edinmek için Yapıcı Metotlar ve Kalıtım başlıklı içeriği okuyabilirsiniz.
Nasıl Exception Fırlatabiliriz ?
Exception sınıflarımızı oluşturduğumuza göre şimdi onları hatalı işlem yapılmasını önlemek amacıyla kontrollü bir şekilde fırlatabiliriz. Örnek senaryo üzerinden giderek sınıfımızı ve metodumuzu oluşturalım;
class UserManager { private static Dictionary<string, string> _users = new Dictionary<string, string> { {"srdrylmz","123456789"}, {"wordpress", "798456132"} }; public void PasswordChange(string userName, string oldPassword, string newPassword) { if (_users.ContainsKey(userName)) { if (_users[userName] != oldPassword) throw new WrongPasswordException(); _users[userName] = newPassword; } else { throw new UserNotFoundException(); } } }
UserManager isimli class içerisinde kod kalabalığını arttırmamak için; kullanıcı adı ve şifre çiftlerini tutan bir Dictionary tanımlayıp, kullanıcının kayıt olup-olmadığını, şifrenin doğru girilip-girilmediğini bu koleksiyon sınıfı üzerinden kontrol ettik. Sizler bu işlemleri veritabanı üzerinden yapabilirsiniz. Dictionary hakkında daha detaylı bilgi edinmek için Dictionary Sınıfı başlıklı içeriği okuyabilirsiniz.
PasswordChange() isimli metodumuzu açıklayacak olursak; İlk olarak parametre olarak gelen kullanıcı adının _Users koleksiyonunda olup olmadığını kontrol ediliyor ve eğer kullanıcı mevcut değilse throw anahtar sözcüğü ile UserNotFoundException istisnası fırlatılıyor. Kullanıcı mevcut ise parametre olarak gelen şifre bilgisinin doğru olup olmadığı kontrol ediliyor ve şifre bilgisi yanlış ise WrongPasswordException istisnası fırlatılıyor. Doğru girildiği takdirde de ilgili kullanıcının şifre bilgisini güncelleniyor.
throw anahtar sözcüğü ile oluşturduğumuz exception sınıflarını nasıl fırlatacağımızı öğrendik, şimdi sıra onları yakalamakta.
UserManager userManager = new UserManager(); try { userManager.PasswordChange("serdaryilmaz", "123465", "6543210"); } catch(Exception ex) { Console.WriteLine(ex.Message); }
_Users koleksiyonunda “serdaryilmaz” adında bir kullanıcı olmadığı için UserNotFoundException istisnasını fırlatacaktır. Ekran çıktısı;
Kullanıcı Adı Hatalı! Press any key to continue . . .
UserManager userManager = new UserManager(); try { userManager.PasswordChange("srdrylmz", "123465", "6543210"); } catch(Exception ex) { Console.WriteLine(ex.Message); }
“srdrylmz” kullanıcısının şifresi yanlış girildiğinden WrongPasswordException istisnasını fırlatacaktır.
Şifre Hatalı! Press any key to continue . . .
Serdar YILMAZ
hocam exception static bir class değil ve bu sınıftan new ile bir nesne üretmedik fakat catch(Exception ex)
ex yazdıktan sonra NOKTA koyarak message property sine erişebiliyoruz bu sınıf static olmadıgı halde ve yeni bir nesne uretmedıgımız halde message propertysine nasıl erişebiliyoruz
Merhaba,
Bir hata oluşması durumunda .NET arkaplanda bir Exception nesnesi oluşturmakta ve o nesnenin içeriğini oluşan hata türüne göre doldurarak geri döndürmektedir. Döndürülen nesne catch blogu tarafından yakalanarak kullanılabilmektedir. “ex” yazdıktan sonra “message” özelliğine erişebilmemizin nedeni; ex’in bir referans olması ve .NET tarafından oluşturulan Exception nesnesinin referansını tutuyor olmasıdır.
public class Student
{
public string Name { get; set; }
public string SurName { get; set; }
}
class StudentManager
{
public void StudentName(Student student)
{
Console.WriteLine(student.Name);
}
}
Benzer şekilde Student sınıfı static bir sınıf olmamasına rağmen StudentManager sınıfı içerisindeki StudentName metodunda parametre olarak yer aldığı için içerisindeki özelliklere StudentName metodu içerisinde erişebilmekteyiz.