Yükleniyor...

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:


// 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:

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:

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.

Breakpoint in code lines

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.

Debugging code lines

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)


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# 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.