İçeriğe geç

Null Reference Exception: 3 Saatlik Maceramız

Şimdi size başıma gelen tuhaf bir olayı anlatacağım, belki sizin de başınıza gelmiştir bu tarz bir şey, kim bilir? Bir zamanlar, evet, birkaç yıl önce diyelim, bir proje üzerinde çalışıyordum. Her şey gayet güzel gidiyordu, kodlar akıyordu, fonksiyonlar yerli yerindeydi. Proje canlıya geçecekti neredeyse ve ben de son rötuşları yapıyordum. Tam her şey yolunda derken, bir anda karşıma çıktı: Null Reference Exception. Ah, o meşhur hata! Sanki ekrana ‘Hooop, yakaladım seni!’ diye bağırıyordu.

Ne olduğunu anlamaya çalıştım ilk başta. Hata mesajı ortada ama tam olarak nerede tetiklendiğini bulmak biraz zaman alıyordu. Debugger’ı açtım, satır satır kodu taradım. Sanki bir dedektif gibi ipuçlarını takip ediyordum ama hata bir hayalet gibiydi, sürekli kaçıyordu. Bir bakıyorsun, bir değişken ‘null’ değil, bir bakıyorsun olmuş ‘null’. İnanın ki sinir bozucu bir durum. Bu arada, o gün hava da epey sıcaktı sanırım, neyse. Yani şey gibi… tam konsantre olamıyordum bir türlü.

İlk başta basit bir şeydir diye düşündüm. ‘Tamam ya, şuradan bir null kontrolü ekleriz, geçer gideriz’ diye düşündüm. Ama nerdeee… O null reference exception denen illet, sanki benimle inatlaşıyordu. Bir yerde düzeltiyorum, başka bir yerde çıkıyordu karşıma. Sanki bir ‘Whack-a-mole’ oyunu oynuyorduk programla ben de o ‘mole’ oluyordum.

Saatler geçmeye başladı. Önce bir saat geçti, sonra iki saat… Üçüncü saate doğru artık durum ciddileşiyordu. Bir yandan proje teslim tarihi yaklaşıyor, bir yandan da bu lanet hata peşimi bırakmıyordu. Kahve tüketimim de hat safhaya ulaşmıştı tabi. Hani bazen olur ya, bir soruna takılırsın ve başka hiçbir şeyi düşünemezsin? İşte tam olarak öyle bir durumdaydım. Kendi programım sınıfta kaldı diyebilirim o an için.

Fakat pes etmek yoktu tabii. Bu benim hatamdı ve benim düzeltmem gerekiyordu. Bu arada aklıma geldi, geçen seferki sorun da böyleydi sanırım. Neyse. Tekrar başa döndüm, hata loglarını iyice incelemeye başladım. Hangi fonksiyonun çağrıldığı, hangi parametrelerin geçtiği… Detay detay baktım. Ve sonunda, gözümden kaçan küçük bir detay yakaladım. Sanırım o ana kadar hiç düşünmediğim bir senaryo tetikleniyordu ve orada bir yerde bir nesne henüz oluşturulmamış oluyordu. İşte o an, sanki beynimde bir ampul yandı.

Neyse efendim, o hatayı çözmek tam olarak 3 saat sürdü. Evet, tam tamına 3 saat! Basit bir null kontrolü için saatlerimi harcadım. Ama öğrendiğim şey paha biçilmezdi. Bazen en karmaşık sorunların çözümü en basit detaylarda gizlidir. Bu arada, bu tür hatalarla karşılaşmamak için ne gibi önlemler alabileceğimize dair Google’da birkaç araştırma yaptım, ilginç sonuçlar çıktı karşımıza.

Öncelikle, kodunuzda değişkenlerinizi kullanmadan önce mutlaka null olup olmadıklarını kontrol edin. Bu kadar basit bir şey bazen hayat kurtarır. Özellikle kullanıcıdan veri alırken, bir API’den veri çekerken veya bir veritabanından okuma yaparken bu kontrolü atlamamak gerekiyor. Ben bu hatayı yaparken, sanırım bir yerde bir veri gelmediğini ve ben de olmayan veriyi kullanmaya çalıştığımı fark ettim. Ne desem ki… işte öyle bir şey.

İkinci olarak, özellikle C# gibi dillerde null propagation operatörlerini (?. ve ?? ) kullanmayı öğrenin. Bu operatörler, kodunuzu daha temiz ve okunabilir hale getirirken, null referans hatalarını da büyük ölçüde azaltır. Mesela şöyle bir şey düşünün: `kullanici.Adres.Sehir?.Adi`. Bu ifade, eğer `kullanici` null değilse `Adres`’i, `Adres` null değilse `Sehir`’i, `Sehir` null değilse `Adi`’ni alacaktır. Eğer herhangi biri null ise, hata vermeden ‘null’ döner. Ne güzel değil mi?

Bir de async/await yapısını kullanırken dikkatli olmak lazım. Asenkron işlemler sırasında bir yerde bir hata oluşup null dönmesi ve bunun doğru şekilde yönetilmemesi de bu hataya yol açabilir. Yani şey gibi, bir fonksiyon bir şey beklerken başka bir şeyle karşılaşması durumu. Bu arada, asenkron programlama üzerine YouTube’da çok güzel anlatımlar var, izlemenizi tavsiye ederim.

İşte böyle bir durum yaşadım. 3 saatimi alan bir hata ama bana önemli dersler verdi. Unutmayın, yazılım geliştirirken her zaman dikkatli olmak, her ihtimali düşünmek gerekiyor. Hata yapmak insani, ama aynı hatayı tekrar yapmak pek de akıllıca değil sanırım. 🙂 Bu arada, bu tarz hataları yakalamak için kullanılan araçlar var ama bazen en iyi araç kendi gözünüz ve mantığınızdır. Ne dersiniz?

Şimdi gelelim bu hatayı nasıl tetikleyebileceğimize ve nasıl düzeltebileceğimize dair basit bir kod örneğine. Diyelim ki elimizde şöyle bir yapı var:

public class Adres {     public string Sehir { get; set; } }

public class Kullanici { public string Isim { get; set; } public Adres Adres { get; set; } }

// Hata veren kısım public void YazdirSehir(Kullanici kullanici) { Console.WriteLine(kullanici.Adres.Sehir); // NullReferenceException burada patlar! }

Bu kodda `kullanici` veya `kullanici.Adres` null ise, `kullanici.Adres.Sehir` satırında hata alırsınız. İşte bu bizim 3 saatimizi yiyen lanet hata. 🙂

Şimdi bunu nasıl düzeltebiliriz? En basit yolu null kontrolü eklemek:

public void YazdirSehirDuzenli(Kullanici kullanici) {     if (kullanici != null && kullanici.Adres != null && kullanici.Adres.Sehir != null)     {         Console.WriteLine(kullanici.Adres.Sehir);     }     else     {         Console.WriteLine("Şehir bilgisi bulunamadı.");     } }

Ya da daha modern bir yaklaşımla null propagation operatörlerini kullanarak:

public void YazdirSehirModern(Kullanici kullanici) {     var sehir = kullanici?.Adres?.Sehir ?? "Şehir bilgisi bulunamadı.";     Console.WriteLine(sehir); }

Böylece hem kodumuz daha kısa oluyor hem de hata alma riskimiz azalıyor. Hani bazen bir kodu okurken ‘Bu nasıl çalışıyor böyle?’ dersin ya, işte bu operatörler sayesinde o karmaşık görünen şeyler aslında çok basit bir mantığa dayanıyor. Bu arada, bu operatörlerin kullanım alanları ve püf noktaları hakkında Reddit’te de bolca tartışma var, göz atabilirsiniz.

Sonuç olarak, Null Reference Exception denen şey bazen can sıkıcı olsa da, onu anlamak ve çözmek geliştirme sürecinin bir parçası. Önemli olan bu tür hatalardan ders çıkarmak ve kodumuzu daha sağlam hale getirmek. Bu arada, benim gibi bu hatayla mücadele eden varsa, umarım bu yazı biraz olsun fikir vermiştir. Ne güzel değil mi? Birbirimize yardım etmek işte bu olsa gerek.