C# Hata Ayıklama (Debugging) Teknikleri
C#’ta hata ayıklama tekniklerini öğrenin. Breakpoint, watch, step into/out ve debug araçlarıyla sorunları hızlıca çözün.
Yazılım geliştirme sürecinde hata ayıklama (debugging), programın beklenmeyen davranışlarını analiz etmek ve hatalı kodu tespit etmek için yapılan sistematik bir süreçtir. C#’ta Visual Studio ve Visual Studio Code gibi araçlar, güçlü debugging yetenekleriyle geliştiricilere adım adım izleme, değişken değerlerini kontrol etme ve uygulamanın akışını analiz etme imkânı sunar.
Debug ve Release Modu Farkı
.NET projelerinde iki temel derleme modu bulunur:
- Debug: Geliştirme aşamasında kullanılır. Hata ayıklamayı kolaylaştıran semboller ve ekstra bilgiler içerir.
- Release: Üretim (yayın) sürümüdür. Optimizasyonlar yapılır, hata ayıklama bilgileri kaldırılır.
// Visual Studio’da üst menüden seçilebilir:
// [Debug ▼] → [Release]
Debug modunda çalışırken program, satır satır izlenebilir ve kod akışı üzerinde tam kontrol sağlanır.
Breakpoints (Durma Noktaları)
Breakpoint, program çalışırken belirli bir satırda durmasını sağlayan işarettir. Bu sayede program o noktaya kadar çalışır ve durduğunda tüm değişkenlerin mevcut değerleri incelenebilir.
class Program
{
static void Main()
{
int a = 5;
int b = 0;
int c = a / b; // Hata: DivideByZeroException
Console.WriteLine(c);
}
}
Yukarıdaki örnekte, int c = a / b; satırına breakpoint koyarak programın burada durmasını sağlayabiliriz.
“Locals” penceresinde a ve b değişkenlerinin değerleri incelenebilir.
Stepping Komutları (Adım Adım İzleme)
Visual Studio’da kodu adım adım çalıştırmak için aşağıdaki kısayollar kullanılır:
- F10 – Step Over: Satırı çalıştırır, alt metotlara girmez.
- F11 – Step Into: Satırdaki metot çağrısının içine girer.
- Shift + F11 – Step Out: Mevcut metottan çıkar.
- F5 – Continue: Sonraki breakpoint’e kadar çalıştırır.
Bu araçlar sayesinde program akışı üzerinde tam kontrol sağlanabilir ve hangi satırda hatanın başladığı net şekilde tespit edilir.
Değişken İzleme (Watch & Autos Penceresi)
Visual Studio, hata ayıklama sırasında değişken değerlerini canlı olarak izleme imkânı sunar:
- Watch Window: Manuel olarak eklenen değişkenlerin değerini izler.
- Locals Window: O anki scope’taki tüm değişkenleri otomatik listeler.
- Autos Window: Son yürütülen birkaç satırla ilişkili değişkenleri gösterir.
Değişken üzerine geldiğinizde çıkan “tooltip” balonunda mevcut değeri anlık olarak görebilirsiniz.
Immediate ve Watch Kullanımı
Immediate Window hata ayıklama sırasında kod yazıp anında çalıştırmanıza olanak tanır. Bu pencere ile değişkenlerin değerini değiştirebilir veya kısa testler yapabilirsiniz.
// Immediate Window örneği:
// ? a + b
// ? myList.Count
// a = 25
Böylece kodu durdurmadan belirli hesaplamaları test edebilir, değişken değerlerini değiştirebilirsiniz.
Conditional Breakpoints (Koşullu Durma Noktaları)
Bazı durumlarda programın her seferinde durması yerine yalnızca belirli koşullarda durmasını isteyebilirsiniz. Bunun için conditional breakpoint kullanılır.
for (int i = 0; i < 100; i++)
{
Console.WriteLine(i);
}
Bu döngüde breakpoint ekledikten sonra “Conditions” menüsüne girip
i == 50 koşulunu tanımlarsanız, program yalnızca 50. adımda durur.
Exception Settings (Hata Yönetimi Ayarları)
Debug → Windows → Exception Settings menüsünden hangi tür hatalarda programın duracağı belirlenebilir.
Örneğin yalnızca NullReferenceException veya InvalidOperationException durumlarında durmasını sağlayabilirsiniz.
Bu özellik özellikle karmaşık uygulamalarda gereksiz durmaların önüne geçer.
Try / Catch Bloklarında Hata Ayıklama
Kod hata yakalama (try / catch) bloğu içinde olsa bile Visual Studio,
“Break on User-Unhandled Exceptions” seçeneği aktifse hatanın olduğu satırda durabilir.
try
{
int[] dizi = new int[3];
dizi[5] = 10; // IndexOutOfRangeException
}
catch (Exception ex)
{
Console.WriteLine("Hata yakalandı: " + ex.Message);
}
Bu sayede istisna oluşmadan hemen önce uygulamanın durumunu inceleyebilirsiniz.
Debug.WriteLine() Kullanımı
Debug.WriteLine() metodu, hata ayıklama sırasında bilgi mesajlarını Output Window’a yazar.
Bu, konsol çıktısını değiştirmeden arka planda log tutmak için kullanışlıdır.
using System.Diagnostics;
class Program
{
static void Main()
{
for (int i = 0; i < 3; i++)
{
Debug.WriteLine($"Adım {i} tamamlandı.");
}
Console.WriteLine("Program bitti.");
}
}
Bu mesajlar yalnızca Debug modunda görülür; Release sürümde çalışmaz.
Loglama ve Hata İzleme
Debugging yalnızca anlık analiz için değil, uygulamanın uzun vadeli takibi için de önemlidir.
Bunun için logging kütüphaneleri (örneğin Serilog, NLog, Microsoft.Extensions.Logging) kullanılabilir.
using Microsoft.Extensions.Logging;
class Program
{
static void Main()
{
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
});
var logger = loggerFactory.CreateLogger<Program>();
try
{
int a = 10, b = 0;
int c = a / b;
}
catch (Exception ex)
{
logger.LogError(ex, "Bir hata oluştu!");
}
}
}
Loglama, hataların sadece geliştirme sırasında değil, canlı sistemlerde de izlenmesini sağlar.
Örnek: Kullanıcı Girişi Debugging
Breakpointi koyduğunuz yerde program duracaktır.
Aşağıdaki örnekte kullanıcı giriş formundaki hatayı adım adım debug ederek tespit ediyoruz.
class LoginService
{
public bool Login(string username, string password)
{
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
throw new ArgumentException("Kullanıcı adı veya şifre boş olamaz.");
return username == "admin" && password == "1234";
}
}
class Program
{
static void Main()
{
var service = new LoginService();
Console.Write("Kullanıcı adı: ");
string? u = Console.ReadLine();
Console.Write("Şifre: ");
string? p = Console.ReadLine();
try
{
bool result = service.Login(u, p);
Console.WriteLine(result ? "Giriş başarılı" : "Geçersiz bilgiler");
}
catch (Exception ex)
{
Console.WriteLine($"Hata: {ex.Message}");
}
}
}
Breakpoint’i herhangi bir satıra koyup adım adım değişkenleri inceleyebilirsiniz.
Breakpoint’i return satırına koyarak, username ve password değerlerini anlık inceleyebilir,
koşulun neden false döndüğünü analiz edebilirsiniz.
En İyi Uygulamalar (Best Practices)
- Her hatayı
try / catchiçine almak yerine, belirli katmanlarda yakalayın (ör. UI veya Service katmanı). Console.WriteLineyerineDebug.WriteLineveya log framework kullanın.- “Step Into” yerine “Step Over” kullanarak gereksiz detaylara girmekten kaçının.
- Koşullu breakpoint’lerle belirli senaryolara odaklanın.
- Hataları test etmek için Exception Simulation tekniklerini kullanın (ör. hatalı input, null değerler).
TL;DR
- Debugging: Programın akışını adım adım izleyip hatayı bulma sürecidir.
- Breakpoint: Kodun belirli bir satırda durmasını sağlar.
- Watch & Immediate: Değişkenleri izleme ve anlık komut çalıştırma araçlarıdır.
- Debug.WriteLine: Geliştiriciye özel log çıktısı sağlar (yalnızca Debug modda).
- Logging: Canlı ortamlarda hata ve olayların kaydını tutar.
- Koşullu breakpoint: Belirli durumlarda durmayı sağlar, performans kazandırır.
İlişkili Makaleler
C# Hata Denetimi (try, catch, finally)
C#’ta try, catch ve finally bloklarını kullanarak hataları yakalamayı ve güvenli hata yönetimi yapmayı örneklerle öğrenin.
C# için Visual Studio / VS Code İpuçları
C# geliştiricileri için Visual Studio ve VS Code ipuçlarını öğrenin. Verimlilik artıran kısayollar ve geliştirme teknikleri.
C# Reflection ve Late Binding
C#’ta Reflection ve Late Binding kullanımını öğrenin. Runtime tip keşfi, dinamik çağrılar ve esnek yapıların örnekleri anlatılıyor.