Exception, yazdığımız programda kullanıcı veya program girdilerine göre oluşabilecek istenmeyen durumlar için kullanılır. Bir nevi programımızın ben senden işleme devam etmek için böyle bir şey vermeni bekliyordum ama sen bana vermediğin için çalışmayı durduruyorum demesidir.
Konsoldan girilen iki sayının çarpımını veren ufak bir program yazalım:
Console.Write("İlk sayıyı giriniz: ");
string strOkunanIlk= Console.ReadLine();
int ilkSayi = int.Parse(strOkunanIlk);
Console.Write("İkinci sayıyı giriniz: ");
string strOkunanIkinci = Console.ReadLine();
int ikinciSayi = int.Parse(strOkunanIkinci);
Console.WriteLine("Sayıların çarpımı: {0} * {1} = {2}", ilkSayi, ikinciSayi, ilkSayi * ikinciSayi);
Yukarıdaki programda bir hata yokmuş gibi gözüküyor fakat kullanıcının girdileriyle programın akışı da değişebilir. Programı tekrardan çalıştırıp sayı yerine harf yazarsak aşağıdaki gibi bir hata alırız:
Bunun nedeni programımız “q” harfini herhangi bir rakama atayamıyor. Dolayısıyla da bir hata fırlatıyor. Bunun önüne geçebilmek için try-catch ifadelerini kullanabiliriz. Bu ifadeler programda bir hata oluştuğunda oluşan hataya göre aksiyon almamızı sağlar ve programın kendi kendini kapatmasının önüne geçer. Kodumuzu aşağıdaki gibi değiştirip tekrardan derleyelim.
try
{
Console.Write("İlk sayıyı giriniz: ");
string strOkunanIlk = Console.ReadLine();
int ilkSayi = int.Parse(strOkunanIlk);
Console.Write("İkinci sayıyı giriniz: ");
string strOkunanIkinci = Console.ReadLine();
int ikinciSayi = int.Parse(strOkunanIkinci);
Console.WriteLine("Sayıların çarpımı: {0} * {1} = {2}", ilkSayi, ikinciSayi, ilkSayi * ikinciSayi);
}
catch (Exception ex)
{
Console.WriteLine("Hata: {0}", ex.Message);
}
Console.ReadKey();
Aynı girdileri verdiğimizde bu sefer programımız yine hata fırlatacak fakat fırlatılan hata catch ifadesine düşecek ve bu hatayı biz karşılayacağız.
Böylece verilen hatayı kendimiz düzelterek istenmeyen durumdan kaçınmış olduk fakat ne pahasına? Şimdi bu try-catch ifadesinin bize zaman kısmında neye mâl olduğuna bakalım:
Stopwatch sure = new Stopwatch();
sure.Start();
try
{
Console.Write("İlk sayıyı giriniz: ");
string strOkunanIlk = "5";
int ilkSayi = int.Parse(strOkunanIlk);
Console.Write("İkinci sayıyı giriniz: ");
string strOkunanIkinci = "q";
int ikinciSayi = int.Parse(strOkunanIkinci);
Console.WriteLine("Sayıların çarpımı: {0} * {1} = {2}", ilkSayi, ikinciSayi, ilkSayi * ikinciSayi);
}
catch (Exception ex)
{
Console.WriteLine("Hata: {0}", ex.Message);
}
sure.Stop();
Console.WriteLine("Geçen süre: {0} ms",sure.Elapsed.TotalMilliseconds);
Console.ReadKey();
Stopwatch nesnesi başlangıç ile bitiş arasında ne kadar zaman geçtiğini kullandığımız bir nesnedir. Kullanıcıdan girişleri bilerek kaldırdım çünkü klavyeden kaynaklı gecikmeleri devre dışı bırakmak istedim. Görüldüğü üzere strOkunanIkinci değerinde bir sayı yerine “q” ifadesi atanmıştır bu da doğal olarak bir hata fırlatılmasına sebep olacaktır. Programın çalışması için geçen süre aşağıdadır:
Şimdi kodu olması gerektiği gibi çalıştırıp ne kadar süre geçtiğine bakalım.
Stopwatch sure = new Stopwatch();
sure.Start();
try
{
Console.Write("İlk sayıyı giriniz: ");
string strOkunanIlk = "5";
int ilkSayi = int.Parse(strOkunanIlk);
Console.Write("İkinci sayıyı giriniz: ");
string strOkunanIkinci = "4";
int ikinciSayi = int.Parse(strOkunanIkinci);
Console.WriteLine("Sayıların çarpımı: {0} * {1} = {2}", ilkSayi, ikinciSayi, ilkSayi * ikinciSayi);
}
catch (Exception ex)
{
Console.WriteLine("Hata: {0}", ex.Message);
}
sure.Stop();
Console.WriteLine("Geçen süre: {0} ms",sure.Elapsed.TotalMilliseconds);
Console.ReadKey();
Görüldüğü üzere kodumuz try-catch ifade düştüğünde 33 ms gibi bir sürede çalışırken her şeyin olması gerektiği gibi olduğu bir durumda 1 ms gibi bir sürede çalışıyor aradaki fark neredeyse 30 kat. Eğer böyle bir ifadeyi bir döngüde kullanırsanız programınız tahmin ettiğinizden çok daha yavaş çalışacaktır. Bunun önüne nasıl geçebiliriz peki? Bu program özelinde, işimize gelmeyen durum kullanıcının sayı dışında bir ifade girmesidir. Eğer try-catch kullanmadan girilen ifadelerin kontrollerini sağlarsak programımız 30 ms gibi sürelerde çalışmaz.
Stopwatch sure = new Stopwatch();
sure.Start();
Console.Write("İlk sayıyı giriniz: ");
string strOkunanIlk = "5";
Console.Write("İkinci sayıyı giriniz: ");
string strOkunanIkinci = "4";
int ikinciSayi, ilkSayi;
if (int.TryParse(strOkunanIlk, out ilkSayi) && int.TryParse(strOkunanIkinci, out ikinciSayi))
{
Console.WriteLine("Sayıların çarpımı: {0} * {1} = {2}", ilkSayi, ikinciSayi, ilkSayi * ikinciSayi);
}
else
{
Console.WriteLine("Yanlış girilen ifadeler var");
}
sure.Stop();
Console.WriteLine("Geçen süre: {0} ms",sure.Elapsed.TotalMilliseconds);
Console.ReadKey();
Kodumuzu yukarıdaki gibi yazıp derlersek aşağıdaki gibi bir sonuç alırız:
Tabiki aradaki küçük farklar bilgisayarın o anki durumuna göre değişkenlik gösteriyor. Fakat 2 hali de try-catch ifadesi kullanılmış halinden kat kat daha iyi.
Toplamak gerekirse eğer programınız için hatalı girdiler olabileceğini biliyorsanız o girdileri kendinizin kontrol ettiğini bir program yazmanız hem sizin için hem de programınız için daha faydalı olacaktır.