using System.Globalization;
namespace _24_Exceptions
{
internal class Program
{
static void Main(string[] args)
{
// Exception beklenmedik hata (error) demektir.
// Hatalar Derleme Zamanı (Compile Time) Hataları ile Çalışma Zamanı (Run Time) Hataları olmak üzere iki çeşittir.
// Compile Time Errors kod yazarken yapılan syntax (söz dizimi) hatalarıdır.
// Eğer proje bu hataları içeriyorsa build edilmez (derlenmez) ve bu hatalar kolaylıkla Visual Studio'nun
// Error List veya Output pencerelerinden görülüp düzeltilebilir.
// Run Time Errors syntax hatası içermeyen bir projenin çalışırken aldığı hatalardır.
// Örneğin bir hesaplama hatası yapılmış olabilir veya beklenen bir işlem gerçekleştirilmiyor
// ya da yanlış gerçekleştiriliyor olabilir.
// Bu hataları yakalamanın en kolay yöntemi kodları debug etmektir.
// Çalışma Zamanı Hataları ayrıca kod yazarken uygun olmayan bir işlemin gerçekleştirilmesi ve bu işlem sonucunda
// uygulamanın çalışmayı sonlandırması (terminate) şeklinde de karşımıza çıkabilir.
// Örnek olarak olmayan bir index üzerinden bir dizinin elemanına ulaşma, olmayan bir dosya üzerinden
// dosya işlemi yapma veya yanlış bir bağlantı bilgisi üzerinden veritabanına erişim verilebilir.
// Bu tip hatalar Exception Handling (Beklenmedik Hata Yönetimi) ile try, catch ve opsiyonel olarak finally anahtar kelimeleri
// kullanılarak yakalanıp hata üzerinden bilgi edinilerek uygulamanın işlemini sonlandırmaması sağlanabilir.
// Her bir beklenmedik hata bir tiptir (sınıf) ve Exception sınıfından miras alır.
// Sadece beklenmedik hatalar için try, catch ve opsiyonel olarak finally kullanılmalıdır.
// Örneğin kullanıcıdan alınan adın ve soyadın boş olması beklenen bir durumdur ve beklenen durumlar mutlaka
// if gibi şart blokları üzerinden kontrol edilmelidir (validasyon).
// Ancak kullanıcıdan string tipinde alınan yaşın integer'a dönüştürülürken içerisinde karakter olması durumunda
// karşılaşılacak beklenmedik hata try, catch ve opsiyonel olarak finally ile yakalanmalıdır.
// Beklenmedik hatalar uygulama güvenlikleri ile ilgili sorunlar çıkarabilir, dikkat edilmezse bu hatalar üzerinden
// uygulamanın içeriğiyle ilgili bilgi alınabilir (örneğin veritabanı yapısı).
// Bu yüzden catch ile yakalanan beklenmedik hatanın detayını kullanıcıya göstermek yerine "İşlem sırasında hata meydana geldi!"
// şeklinde bir bilgilendirme yapılmalıdır. Eğer istenirse beklenmedik hatalar dosya, veritabanı, vb. üzerinden loglanabilir.
// try, catch ve opsiyonel olarak finally kodların bir kısmını çevreleyecek şekilde kullanılabileceği gibi
// tüm kodları çevreleyecek şekilde de kullanılabilir.
#region Exceptions 1
try // içerisindeki kodları çalıştırmayı dener
{
string[] ogrenciler = new string[3];
ogrenciler[0] = "Çağıl";
ogrenciler[1] = "Angel";
ogrenciler[2] = "Leo";
ogrenciler[3] = "Luna"; // index out of bounds exception'ı fırlatacaktır çünkü dizi 3 elemanlı
Console.WriteLine("Öğrenciler:\n");
foreach (string ogrenci in ogrenciler)
{
Console.WriteLine(ogrenci);
}
}
catch // eğer try içerisinde çalıştırılması denenen kodlar beklenmedik hata fırlatırsa yakalar
{
Console.WriteLine("İşlem sırasında hata meydana geldi!");
}
#endregion
Console.WriteLine();
#region Exceptions 2
try
{
int sayi1 = 13;
int sayi2 = 0;
int sonuc = sayi1 / sayi2; // beklenmedik hata verecektir çünkü herhangi bir sayının 0'a bölümü tanımsızdır
Console.WriteLine(sayi1 + " / " + sayi2 + " = " + sonuc);
}
catch (Exception exc) // eğer istenirse beklenmedik hatanın detayına Exception tipindeki objenin exc referansı üzerinden ulaşılabilir
{
Console.WriteLine("İşlem sırasında hata meydana geldi!");
Console.WriteLine(exc.Message); // beklenmedik hatanın Message özelliği üzerinden bilgisi kullanıcıya gösterilmemelidir,
// genelde loglama veya debug için kullanılır
if (exc.InnerException is not null)
Console.WriteLine(exc.InnerException.Message); // eğer exc'nin Exception tipindeki InnerException özelliği null değilse
// bu özelliğin Message özelliği üzerinden beklenmedik hata ile ilgili
// daha detaylı bilgiye ulaşılabilir, Entity Framework işlemleri
// dışında genelde InnerException kullanılmaz
}
#endregion
Console.WriteLine();
#region Exceptions 3
try
{
string dosyaYolu = @"C:\personel.txt"; // belirtilen dosya yolunda böyle bir dosya bulunmuyor
string icerik = File.ReadAllText(dosyaYolu);
Console.WriteLine("Dosya içeriği:\n" + icerik);
}
catch (FileNotFoundException exc) // FileNotFoundException Exception sınıfından miras aldığı için eğer özellikle dosya bulunamadı
// beklenmedik hatalası yakalanmak isteniyorsa Exception yerine kullanılabilir,
// genelde tüm beklenmedik hataları yakalamak istediğimizden Exception tipini kullanırız
{
Console.WriteLine("Dosya bulunamadı hatası meydana geldi!");
Console.WriteLine(exc.Message);
}
#endregion
Console.WriteLine();
#region Exceptions 4
try
{
string dosyaYolu = "C:\\personel.txt"; // belirtilen dosya yolunda böyle bir dosya bulunmuyor
string icerik = File.ReadAllText(dosyaYolu); // dosya bulunmadığından File Not Found Exception fırlatacaktır
string isim = null;
isim = isim.Trim(); // isim değişkeni null olarak atandığından null üzerinden bir özellik veya method kullanımı
// Null Reference Exception fırlatacaktır
Console.WriteLine("Dosya içeriği:\n" + icerik);
Console.WriteLine("İsim: " + isim);
}
catch (FileNotFoundException exc) // isteğe göre birden çok catch kullanılarak farklı tiplerde exception'lar yakalanabilir,
// sadece dosya bulunamadı beklenmedik hatasını yakalar
{
Console.WriteLine("File Not Found Exception meydana geldi!");
Console.WriteLine(exc.Message);
}
catch (NullReferenceException exc) // sadece null referans beklenmedik hatasını yakalar
{
Console.WriteLine("Null Reference Exception meydana geldi!");
Console.WriteLine(exc.Message);
}
catch (Exception exc) // null referans veya dosya bulunamadı beklenmedik hataları dışındakileri yakalar
{
Console.WriteLine("Exception meydana geldi!");
Console.WriteLine(exc.Message);
}
#endregion
Console.WriteLine();
#region Exceptions 5
try
{
int sayi;
Console.Write("Örnek için uygulamayı iki kere çalıştırıp önce tam sayı sonra karakter giriniz: ");
sayi = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("try bloğu çalıştı (Sayı: " + sayi + ")");
}
catch (Exception exc)
{
Console.WriteLine("catch bloğu çalıştı (" + exc.Message + ")");
}
finally // try da çalışsa catch de çalışsa her zaman finally çalışır, yazmak zorunlu değildir, ihtiyaca göre kullanılır
{
Console.WriteLine("finally bloğu çalıştı");
}
// try da çalışsa catch de çalışsa finally de çalışsa bu satırdan itibaren yazılan kodlar çalıştırılmaya devam eder
#endregion
Console.WriteLine();
#region Exceptions 6
try
{
DateTime date = TarihGetir("13/01/2023", "en-US"); // 01.13.2023 diye 13. aya sahip bir tarih olmadığından TarihGetir methodu
// kendi içerisinde exception objesini yakalayıp throw ederek buradaki
// try catch bloğunda exception objesinin yakalanması sağlanır
// ve exception objesi catch'e gönderilir
Console.WriteLine("Date: " + date);
}
catch (Exception exc)
{
Console.WriteLine("Tarih getirilirken hata meydana geldi!");
Console.WriteLine(exc.Message);
Console.WriteLine(exc.StackTrace); // Exception objesinin StackTrace özelliği üzerinden beklenmedik hatanın izine,
// örneğin hangi kod satırında beklenmedik hata meydana geldi, ulaşılabilir
}
#endregion
Console.WriteLine();
#region Exceptions 7
try
{
DateTime tarih = DateTime.Parse("32.12.2023", new CultureInfo("tr-TR")); // 32 Aralık 2023 diye bir tarih olmadığından catch'e düşecektir
Console.WriteLine("Tarih: " + tarih);
}
catch // catch ile yakalanan Exception objesi throw ile içinde çalıştırılan methodun dışına fırlatılabilir,
// burada Main methodu içerisinden throw ettiğimizden exception objesi konsola yazdırılır
{
throw; // Main methodu içerisinde kullanılan throw programı sonlandırır
}
#endregion
}
static DateTime TarihGetir(string tarih, string bolge)
{
try
{
return DateTime.Parse(tarih, new CultureInfo(bolge));
}
catch
{
throw; // catch ile yakalanan Exception objesi throw ile içinde çalıştırılan methodun dışına fırlatılabilir,
// burada TarihGetir methodu içerisinden throw ettiğimizden exception objesi TarihGetir methodunun çağrıldığı yerde
// yani Main methodu içerisinde try catch bloğu üzerinden yakalanır,
// methodun çağrıldığı yerde try catch bloğu ile yakalanan fırlatılmış beklenmedik hata programı sonlandırmaz
}
// burada try catch kullanmasaydık yine beklenmedik hata methodun çağrıldığı yerde try catch kullandığımızdan yakalanabilecekti,
// dolayısıyla burada try catch yazmasak da olurdu
}
}
}