C# İstisna Yönetimi
[[academy-video-youtube({"vid": "LSkbnpjCEkk", "start_time": "0", "title": "C# Exception Handling", "creator": "Tim Corey", "length": "59m 46s"})]]
İstisna yönetimi, sağlam uygulama geliştirmede kritik bir unsurdur. Tim Corey'nin 'C#'ta İstisnaların Yönetimi - Ne zaman yakalayacaklarını, nerede yakalayacaklarını ve nasıl yakalayacaklarını',' videosu, istisnaların ne olduğunu, nasıl yönetileceğini ve nerede yönetileceğini ayrıntılı olarak açıklar.
Bu makale, Tim Corey'nin videosunu kullanarak C#'ta İstisna yönetimini açıklamayı hedefler. Bu, geliştiricilerin program yürütmeleri sırasında ortaya çıkan hata ve olağanüstü durumları yönetmesine olanak tanıyan güçlü bir özelliktir. try, catch ve finally bloklarını kullanarak, C# çalışma zamanı hatalarını yönetmek, istisnaları yazmak ve program akışını sürdürmek için yapılandırılmış bir yol sunar.
Giriş
Tim, birçok geliştiricinin istisnalar ve onların yönetimi hakkında yanlış bir görüşe sahip olduğunu açıklayarak başlar. Daha sağlam uygulamalar oluşturmak için istisnaların ne olduğunu ve bunların nerede ve nasıl doğru şekilde yönetilmesi gerektiğini anlamanın önemine vurgu yapar.
Demo Konsol Uygulaması Oluşturma
Tim, istisna işlenmesini göstermek için Visual Studio 2017'de bir konsol uygulaması oluşturur. Yeni konuları test etmek için konsol uygulamalarını kullanmayı öneriyor çünkü bu uygulamalar en az kurulum gerektirir ve çalışması kolaydır.
using System;
namespace ExceptionsDemo
{
class Program
{
static void Main(string[] args)
{
// Placeholder for input and output operations
Console.ReadLine();
}
}
}using System;
namespace ExceptionsDemo
{
class Program
{
static void Main(string[] args)
{
// Placeholder for input and output operations
Console.ReadLine();
}
}
}Bir Sınıf Kütüphanesi Oluşturma
Tim, çözümün içine farklı yöntemlerin birbirini arayacağı gerçek dünya senaryosunu simüle eden bir sınıf kütüphanesi ekler.

Varsayılan sınıfı siler ve DemoCode adında yeni bir sınıf oluşturur.
public class DemoCode
{
// Method to retrieve a number based on the provided position
public int GetNumber(int position)
{
int[] numbers = { 1, 4, 7, 2 };
return numbers[position];
}
// Intermediate method calls GetNumber
public int ParentMethod(int position)
{
return GetNumber(position);
}
// Top-level method calls ParentMethod
public int GrandparentMethod(int position)
{
return ParentMethod(position);
}
}public class DemoCode
{
// Method to retrieve a number based on the provided position
public int GetNumber(int position)
{
int[] numbers = { 1, 4, 7, 2 };
return numbers[position];
}
// Intermediate method calls GetNumber
public int ParentMethod(int position)
{
return GetNumber(position);
}
// Top-level method calls ParentMethod
public int GrandparentMethod(int position)
{
return ParentMethod(position);
}
}DemoCode sınıfı birbirini arayan yöntemler içerir ve nihayetinde verilen pozisyona göre bir dizi içinden bir sayı alır.
Bir İstisnayı Simüle Etme
Tim, uygulamanın başarılı olmaktan ziyade başarısızlıkları göstermek üzere tasarlandığını açıklar. Geçersiz bir pozisyonu GrandparentMethod'a ileterek bir sınır dışı istisnası tanıtır.
DemoCode demo = new DemoCode();
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");DemoCode demo = new DemoCode();
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");Yukarıdaki kodu geçersiz bir pozisyonla çalıştırmak, bir IndexOutOfRangeException ile sonuçlanır. Tim, Visual Studio hata ayıklayıcısının sorunu nasıl vurguladığını ve istisna hakkında ayrıntılı bilgi sağladığını gösterir.
try-catch Kullanımını Yanlış Yapma
Tim, geliştiricilerin try-catch bloklarını ilk öğrendiklerinde sıkça yaptığı bir hatayı açıklar. Çoğunlukla bir istisna bekledikleri kod bloğunu sararlar ki bu, yanlış işleme yol açabilir.
try
{
int output = 0;
output = numbers[position];
return output;
}
catch (Exception ex)
{
// Avoid returning default values that can mask the problem
return 0;
}try
{
int output = 0;
output = numbers[position];
return output;
}
catch (Exception ex)
{
// Avoid returning default values that can mask the problem
return 0;
}Tim, bu yaklaşımın problemli olduğunu çünkü istisnayı gizlediğini ve yanlış varsayımlarla çalışmaya devam ettiğini vurgular. Örneğin, varsayılan değer olarak 0 döndürmek uygun olmayabilir ve daha fazla sorun yaratabilir.
Doğru İstisna İşleme
Tim, istisnaların uygulamada beklenmedik durumlar hakkında kritik bilgi sağladığını vurgular. Uygulama bu tür bir durumda doğru işleme olmadan çalışmya devam ederse, daha fazla hata ve veri bozulmasına yol açabilir.
İstisnaları yutmaktansa, onları uygun şekilde ele almak önemlidir. İşte daha iyi bir yaklaşım:
try
{
return numbers[position];
}
catch (Exception ex)
{
// Log the exception or handle it appropriately
Console.WriteLine(ex.Message);
throw; // Re-throw the exception to be handled by a higher-level handler
}try
{
return numbers[position];
}
catch (Exception ex)
{
// Log the exception or handle it appropriately
Console.WriteLine(ex.Message);
throw; // Re-throw the exception to be handled by a higher-level handler
}İstisnayı yeniden atarak, sorunun yayılmasını ve gerekiyorsa daha yüksek bir düzeyde ele alınmasını sağlarsınız.
Kullanıcıya Faydalı Bilgi Sağlama
Tim, bazı istisnalar uygulamayı çökertmeden zarifçe ele alınabilse de kullanıcıya faydalı geri bildirim sağlamanın önemli olduğunu açıklar. Örneğin, işlemi yeniden deneme seçeneği içeren bir mesaj kutusu veya bildirim göstermek.
Daha Fazla Faydalı Bilgi: StackTrace
Tim, istisna nesnesinin StackTrace özelliğini kullanarak istisnanın nerede meydana geldiği hakkında ayrıntılı bilgi almanın nasıl yapılacağını gösterir. Bu, sınıf, yöntem ve satır numarasını içerir ki bu, hata ayıklama için paha biçilmezdir.
try
{
return numbers[position];
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
throw;
}try
{
return numbers[position];
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
throw;
}StackTrace özelliği, sorunlu kodun tam yerini belirlemeye yardımcı olan çağrı yığınının tam izini sağlar.
try-catch Bloklarının Doğru Yerleştirilmesi
Tim, istisna işlemenin onları yalnızca yakalamakla kalmayıp aynı zamanda try-catch bloklarınızı nereye yerleştireceğinizi bilmekle ilgili olduğunu açıklar. Anahtar, try-catch bloklarını istisnayı uygun şekilde işleyecek kadar bağlam bulunduğunuz bir düzeye yerleştirmektir.
Yanlış Yerleştirmenin Örneği
Bir try-catch bloğunu çağrı yığınının derinliklerine yerleştirmek genellikle istisnayı etkili bir şekilde işlemeyi engeller çünkü daha üst düzey işlemlerin bağlamından yoksunsunuzdur.
// Deep level exception handling (not ideal)
try
{
return numbers[position];
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}// Deep level exception handling (not ideal)
try
{
return numbers[position];
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}Uygun Yerleştirmenin Örneği
try-catch bloğunu kullanıcı arayüzü veya uygulamanın giriş noktası gibi üst düzeyde yerleştirmek, işlemin tam bağlamı ile istisnaları işlemeye olanak tanır.
try
{
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}try
{
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}Bu şekilde, kullanıcılara daha bilgilendirici mesajlar sağlayabilir ve uygulamanın çalışmaya devam edip edemeyeceğine ya da sonlandırılması gerekip gerekmediğine karar verebilirsiniz.
Yığın İzleme Bilgisi
Tim, istisnaların teşhisinde yığın izleme bilgisinin önemini vurgular. Yığın izleme, istisnanın meydana geldiği yer ve ona yol açan yöntem çağrıları zinciri gösteren ayrıntılı bir çağrı geçmişi sağlar.
try
{
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}try
{
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}Bu çıkış, istisnanın tam yerini ve kodun içinden geçtiği yolu verir, sorunu daha kolay hata ayıklama ve düzeltme sağlar.
Mantık İşlemenin Gösterimi
Tim, mantığın uygun seviyede ele alınmasını nasıl göstereceğini gösterir. Örneğin, bir veritabanı bağlantısını açma ve kapatma sorumluluğuna sahip bir yöntem, kaynakların düzgün şekilde yönetildiğinden emin olmak için istisnaları işlemelidir.
public int GrandparentMethod(int position)
{
try
{
Console.WriteLine("Open database connection");
int output = ParentMethod(position);
Console.WriteLine("Close database connection");
return output;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw; // Ensure the exception is propagated
}
}public int GrandparentMethod(int position)
{
try
{
Console.WriteLine("Open database connection");
int output = ParentMethod(position);
Console.WriteLine("Close database connection");
return output;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw; // Ensure the exception is propagated
}
}Bu örnekte, bir istisna meydana gelirse, veritabanı bağlantısı düzgün şekilde kapanmaz, bu da potansiyel kaynak sızıntılarına yol açar. try-catch bloğu ekleyerek, bir istisna meydana gelse bile bağlantının kapandığından emin olabilirsiniz.
finally Bloğunu Kullanma
Tim, istisna meydana gelip gelmemesine bakılmaksızın belirli kodun çalışmasını garanti eden finally bloğunu tanıtır. Bu, özellikle veritabanı bağlantılarını kapatmak gibi kaynakları temizlemek için yararlıdır.
public int GrandparentMethod(int position)
{
try
{
Console.WriteLine("Open database connection");
int output = ParentMethod(position);
return output;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw; // Re-throw the exception to ensure it's handled by a higher-level handler
}
finally
{
Console.WriteLine("Close database connection");
}
}public int GrandparentMethod(int position)
{
try
{
Console.WriteLine("Open database connection");
int output = ParentMethod(position);
return output;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw; // Re-throw the exception to ensure it's handled by a higher-level handler
}
finally
{
Console.WriteLine("Close database connection");
}
}finally bloğu, try ve catch bloklarından sonra çalışır, bir istisna atılsa bile bağlantının kapatılmasını sağlar.
throw İfadesi
Tim, istisnaların çağrı yığınına iletilmesi için yeniden atılmasının önemini açıklar. Bu, yüksek düzeydeki işlemcilerin istisnaları uygun şekilde işlemesini sağlar.
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw; // Re-throws the exception to be handled by the calling method
}catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw; // Re-throws the exception to be handled by the calling method
}throw; ile istisnayı yeniden atmak istisna yığınının tam olarak korunmasını sağlar, bu da hata ayıklama için değerli bağlam sunar.
İstisnaları Uygun Şekilde Yukarı İtme
Tim, istisnaların çağrı yığını boyunca baloncuk gibi yukarı yollarını gösterir. Her yöntem bir try-catch bloğu olup olmadığını kontrol eder ve istisnayı ya işle ya da çağrıcıya iletir.
try
{
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}try
{
int result = demo.GrandparentMethod(4); // This will cause an IndexOutOfRangeException
Console.WriteLine($"The value at the given position is {result}");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}Bu örnekte, GrandparentMethod istisnayı yakalar, kaydeder ve yeniden atar. Konsol uygulamasındaki üst düzey try-catch bloğu, ardından istisnayı işler ve hata mesajını ve yığın izini gösterir.
İstisna İşlemede Yaygın Hatalar
Tim geliştiricilerin istisnaları işlerken yaptığı bazı yaygın hatalara dikkat çeker:
throw ex; kullanmak:
Yığın izini yeniden yazar ve değerli bağlamı kaybeder.
- Örnek:
catch (Exception ex) { // Incorrect throw ex; // Rewrites stack trace }catch (Exception ex) { // Incorrect throw ex; // Rewrites stack trace }
Yeni Bir İstisna Atma:
Özelleştirilmiş bir mesaj ile yeni bir istisna oluşturma fakat orijinal yığın izini kaybetme.
- Örnek:
catch (Exception ex) { // Incorrect throw new Exception("I blew up"); }catch (Exception ex) { // Incorrect throw new Exception("I blew up"); }
Yığın İzini Kaybetmeden Yeni Bir İstisna Oluşturma
Tim, orijinal yığın izini korurken yeni bir istisna oluşturmanın yolunu açıklar. Bu, hala orijinal hatanın bağlamını korurken daha anlamlı bir hata mesajı veya farklı bir istisna türü sağlamak istediğinizde yararlıdır.
catch (Exception ex)
{
throw new ArgumentException("You passed in bad data", ex);
}catch (Exception ex)
{
throw new ArgumentException("You passed in bad data", ex);
}Orijinal istisnayı (ex) iç istisna olarak geçirerek, hata ayıklama için çok önemli olan orijinal yığın izini korursunuz.
Yığın İzini Korumak
Tim, yeni bir istisna oluştururken orijinal istisnanın mesajına ve yığın izine nasıl erişileceğini gösterir.
catch (Exception ex)
{
Console.WriteLine("You passed in bad data");
Console.WriteLine(ex.StackTrace);
throw new ArgumentException("You passed in bad data", ex);
}catch (Exception ex)
{
Console.WriteLine("You passed in bad data");
Console.WriteLine(ex.StackTrace);
throw new ArgumentException("You passed in bad data", ex);
}Bu, yukarı yığılan istisnanın hem yeni mesajı hem de orijinal istisna ayrıntılarını içermesini sağlar.
İç İstisnalar Arasında Döngü Yapmak
Tim, iç istisnaların mesajlarını ve yığın izlerini çıkarmak için tüm iç istisnalar arasında döngü yapmayı sağlayan bir yöntem sunar.
catch (Exception ex)
{
Exception inner = ex;
while (inner != null)
{
Console.WriteLine(inner.StackTrace);
inner = inner.InnerException;
}
throw;
}catch (Exception ex)
{
Exception inner = ex;
while (inner != null)
{
Console.WriteLine(inner.StackTrace);
inner = inner.InnerException;
}
throw;
}Bu döngü, her iç istisnayı üzerinden geçerek yığın izini basar ve tüm istisna katmanlarının hesaba katıldığından emin olur.
Farklı İstisnaları Farklı Şekilde İşleme
Tim, birden fazla catch bloğu kullanarak farklı türdeki istisnaları nasıl işlemeye odaklanır. Bu, istisna türüne göre özel işleme olanak tanır.
try
{
// Code that might throw an exception
}
catch (ArgumentException ex)
{
Console.WriteLine("You gave us bad information. Bad user!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}try
{
// Code that might throw an exception
}
catch (ArgumentException ex)
{
Console.WriteLine("You gave us bad information. Bad user!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}Bu örnekte, ArgumentException özellikle bir özelleştirilmiş mesaj basarak işlenirken, diğer tüm istisnalar istisna mesajı ve yığın izini basan genel bir işlemciye düşer.

Çoklu Catch Bloklarında Düzenin Önemi
Tim, çoklu catch blokları kullanırken düzenin önemini vurgular. En özel istisnalar önce yakalanmalı, ardından daha genel istisnalar gelmelidir.
try
{
// Code that might throw an exception
}
catch (ArgumentException ex)
{
Console.WriteLine("You gave us bad information. Bad user!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}try
{
// Code that might throw an exception
}
catch (ArgumentException ex)
{
Console.WriteLine("You gave us bad information. Bad user!");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}Daha genel bir catch bloğu, özel bir bloktan önce görünüyorsa, tüm istisnaları yakalar ve özel catch bloğu hiçbir zaman ulaşılmaz hale gelir, derleme hatalarına yol açar.
Sonuç
C#'daki istisna yönetimi üzerine Tim Corey'nin gelişmiş video rehberi, yeni istisnalar yaratma, yığın izlerini koruma ve birden fazla catch bloğunu etkili şekilde kullanma konularındaki kritik teknikleri kapsar. En iyi uygulamalarını takip ederek, geliştiriciler istisnaları zarifçe işleyen ve değerli hata ayıklama bilgileri sağlayan sağlam uygulamalar oluşturabilir.

