Clear        


                
                    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
        }
    }
}