C# İstisna Yönetimi
İstisna yönetimi sağlam uygulama geliştirmesi için hayati bir yönüdür. Tim Corey'nin "C#'da İstisnalar Nasıl Ele Alınır - Ne zaman yakalamalı, nerede yakalamalı ve nasıl yakalamalı" videosu, istisnaların ne olduğuna, nasıl ele alınacağına ve nerede ele alınacağına dair detaylı bir açıklama sağlar.
Bu makale, Tim Corey'nin videosunu kullanarak C#'da İstisna Yönetimi'ni açıklamayı amaçlamaktadır. Bu, geliştiricilerin program yürütme sırasında ortaya çıkan hatalar ve istisnai durumları yönetmelerini sağlayan güçlü bir özelliktir. Deneme, yakalama ve nihayet bloklarını kullanarak, C# zamanında gerçekleşen hataları ele almak, istisnaları günlüğe kaydetmek ve program akışını sürdürmek için yapılandırılmış bir yol sağlar.
Giriş
Tim, birçok geliştiricinin istisnalar ve bunların işlenmesi 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 düzgün bir şekilde ele alınacağını anlamanın önemini vurgular.
Bir Demo Konsol Uygulaması Oluşturma
Tim, istisna yönetimini göstermek için Visual Studio 2017'de bir konsol uygulaması oluşturur. Yeni konuların test edilmesi için konsol uygulamalarını kullanmayı önerir çünkü bunlar minimum 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 Kitaplığı Oluşturma
Tim, farklı yöntemlerin birbiriyle çağrışım yaptığı gerçek bir senaryoyu simüle etmek için çözümü sınıf kitaplığına ekler.

Varsayılan sınıfı siler ve DemoKod adlı 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);
}
}DemoKod sınıfı, en sonunda verilen konuma göre bir diziden bir numara döndüren birbirini çağıran yöntemler içerir.
Bir İstisnayı Simüle Etme
Tim, uygulamanın başarıları değil, başarısızlıkları göstermek için tasarlandığını açıklar. BüyükbabaMetodu'na geçerli bir pozisyon vermeyerek bir sınırların dışında istisna 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 kodun geçersiz bir pozisyon ile çalıştırılması, bir IndexOutOfRangeException ile sonuçlanır. Tim, Visual Studio hata ayıklayıcısının sorunu nasıl vurguladığını ve istisna ile ilgili ayrıntılı bilgi sunduğunu gösterir.
try-catch NASIL KULLANILMAZ
Tim, geliştiricilerin try-catch bloklarını ilk öğrendiklerinde yaygın bir hata yaptığını açıklar. Çoğunlukla bir istisna meydana gelebileceğini düşündükleri kod bloğunun tamamını sararlar, bu da yanlış ele almaya 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, istisnayı gizlediği ve yanlış varsayımlarla yürütmeye devam ettiği için sorunlu olduğunu vurgular. Örneğin, varsayılan bir değer olarak 0 döndürmek uygun olmayabilir ve daha fazla soruna neden olabilir.
Doğru İstisna Yönetimi
Tim, istisnaların uygulamadaki beklenmedik durumlar hakkında kritik bilgi sağladığını vurgular. Uygulamanın bu durumda uygun şekilde ele alınmadan devam etmesi, daha fazla hata ve veri bozulmasına yol açabilir.
İstisnaları yutmaktan ziyade, bunları 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 fırlatarak, sorunun iletilmesini sağlarsınız ve eğer gerekirse daha yüksek bir düzeyde ele alınabilir.
Kullanıcıya Yararlı Bilgi Sağlama
Tim, bazı istisnaların uygulamanın çökmeden zarafetle ele alınabileceğini ancak kullanıcılara yararlı geri bildirim sağlamanın önemli olduğunu açıklar. Örneğin, işlemi yeniden deneme seçeneğiyle bir mesaj kutusu veya bildirim göstermek.
Daha Yararlı Bilgi: StackTrace
Tim, istisna nesnesinin StackTrace özelliğini, istisnanın nerede meydana geldiğiyle ilgili ayrıntılı bilgi almak için nasıl kullanabileceğini gösterir. Bu, sınıf, yöntem ve satır numarasını içerir, bu da 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 çağrı yığınının tam bir izini sağlar, geliştiricilerin sorunun tam yerini belirlemelerine yardımcı olur.
try-catch'in Doğru Yerleştirilmesi
Tim, istisnaları doğru şekilde ele almanın sadece onları yakalamakla ilgili olmadığını, aynı zamanda try-catch bloklarınızı nereye yerleştireceğinizi bilmekle ilgili olduğunu açıklar. Anahtar, istisnayı uygun şekilde ele almak için yeterli bağlamı olan bir seviyeye try-catch bloklarını yerleştirmektir.
Yanlış Yerleştirme Örneği
Çağrı yığınının derinliklerinde bir try-catch bloğu yerleştirmek genellikle istisnayı etkili bir şekilde ele almanıza olanak tanımaz çünkü üst düzey işlemlerin bağlamına sahip olmazsınız.
// 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;
}Doğru Yerleştirme Örneği
Try-catch bloğunu en üst düzeyde, örneğin kullanıcı arayüzü veya uygulamanın giriş noktası gibi yerleştirmek, tüm işlemin bağlamını sağlayarak istisnaları ele almanıza 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ıya daha bilgilendirici mesajlar sunabilir ve uygulamanın çalışmaya devam edip edemeyeceğine veya sonlandırılıp sonlandırılacağına karar verebilirsiniz.
Yığın İzleme Bilgileri
Tim, istisnaları teşhis etmede yığın izleme bilgilerinin önemini vurgular. Yığın izleme, istisnanın nerede meydana geldiğini ve ona yol açan yöntem çağrısı zincirini gösteren detaylı 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 çıktı, istisnanın tam yerini ve yürütülen kod yolunu verir, düzeltmeyi ve sorunu düzeltmeyi kolaylaştırır.
Mantığın Yönetimi Gösterimi
Tim, mantığı uygun seviyede nasıl ele alabileceğinizi gösterir. Örneğin, bir yöntemin bir veritabanı bağlantısını açma ve kapama sorumluluğu varsa, kaynakların düzgün yönetildiğinden emin olmak için istisnaları ele alması gerekir.
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 kapatılmaz ve olası kaynak sızıntılarına yol açar. Bir try-catch bloğu ekleyerek, bir istisna meydana gelse bile bağlantının kapatılmasını sağlayabilirsiniz.
finally Blokunu Kullanma
Tim, bir istisna meydana gelirse bile belirli bir kodun çalışacağını garanti eden nihayet blokunu tanıtır. Bu, özellikle veritabanı bağlantılarını kapatma gibi kaynakları temizlemek için kullanışlı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");
}
}Nihayet bloğu, deneme ve yakalama bloklarından sonra çalışır; bir istisna atılsa bile bağlantının kapatıldığını garanti eder.
throw İfadesi
Tim, istisnaları çağrı yığınına yukarı doğru iletmek için yeniden fırlatma önemini açıklar. Bu, üst düzey işlemcilerin istisnaları uygun şekilde işlemelerini 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
}İstisnayı throw; ile yeniden fırlatmak; tam yığın izini korur, hata ayıklama için değerli bir bağlam sağlar.
Exception'ları Uygun Şekilde Yükseltme
Tim, exception'ların çağrı yığını üzerinden nasıl yükseldiğini gösteriyor. Her metod bir try-catch bloğu kontrol eder ve ya exception'ı yönetir ya da çağrı yapan metoda 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 exception'ı yakalar, kaydeder ve tekrar fırlatır. Konsol uygulamasındaki üst düzey try-catch bloğu daha sonra exception'ı ele alır ve hata mesajını ve yığın izini gösterir.
Exception Yönetiminde Yaygın Hatalar
Tim, geliştiricilerin exception'ları yönetirken yaptıkları yaygın hatalardan birkaçını vurguluyor:
Kullanmak throw ex;:
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 Exception fırlatmak:
Özelleştirilmiş bir mesajla yeni bir exception oluşturmak, ancak orijinal yığın izini kaybetmek.
- Örnek:
catch (Exception ex) { // Incorrect throw new Exception("I blew up"); }catch (Exception ex) { // Incorrect throw new Exception("I blew up"); }
Orijinal Yığın İzini Kaybetmeden Yeni Bir Exception Oluşturma
Tim, orijinal yığın izini koruyarak nasıl yeni bir exception oluşturulacağını açıklıyor. Bu, daha anlamlı bir hata mesajı veya farklı bir exception türü sağlamak istediğinizde, orijinal hatanın bağlamını korumak için kullanışlı olabilir.
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 exception'ı (ex) iç exception olarak ileterek, hata ayıklama için hayati önem taşıyan orijinal yığın izini muhafaza edersiniz.
Yığın İzi Bilgisini Koruma
Tim, yeni bir exception oluştururken orijinal exception'ın mesajını ve yığın izini nasıl erişeceğini gösteriyor.
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ığına fırlatılan exception'ın hem yeni mesajı hem de orijinal exception detaylarını içermesini sağlar.
İç Exceptionlar Arasında Döngü Yapma
Tim, iç exception'ların tüm mesajlarını ve yığın izlerini çıkarmak için bir döngü yöntemi sağlar.
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ç exception'ı tarar, yığın izini yazdırır ve tüm exception katmanlarının hesaba katılmasını sağlar.
Farklı Exceptionlar Farklı Şekilde Yönetme
Tim, birden çok catch bloğu kullanarak farklı türdeki exception'ların nasıl yönetileceğini tartışıyor. Bu, exception türüne dayalı olarak özel yönetim sağlar.
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 özel olarak bir özel mesaj yazdırılarak ele alınırken, diğer tüm exception'lar exception mesajını ve yığın izini yazdıran genel bir yöneticiye düşer.

Birden Çok Catch Bloğunda Sıralamanın Önemi
Tim, birden çok catch bloğu kullanırken sıralamanın önemine vurgu yapıyor. En özel exception'lar önce yakalanmalı, ardından daha genel exception'lar takip edilmelidir.
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);
}Eğer daha genel bir catch bloğu özel birinden önce görünürse, tüm exception'ları yakalar ve özel catch bloğu asla ulaşılamaz, bu da derleme hatalarına yol açar.
Sonuç
Tim Corey'nin C#'da exception yönetimi üzerine gelişmiş video rehberi, yeni exception'lar oluşturma, yığın izlerini koruma ve birden çok catch bloğunu etkili bir şekilde kullanma için kritik teknikleri kapsar. Onun en iyi uygulamalarını takip ederek, geliştiriciler exception'ları nazik bir şekilde ele alan ve değerli hata ayıklama bilgileri sağlayan sağlam uygulamalar oluşturabilir.

