Bulut Altyapı

C# 16 Unsafe Yeniden Doğuyor: Bellek Güvenliğinde Yeni Çağ

Açık konuşayım, ilk okuyunca ben de “yine mi unsafe tartışması?” dedim. Sonra GitHub’daki PR’a biraz gömülünce fikir değişti; bu sefer işin rengi farklı. C# ekibi unsafe anahtar kelimesini neredeyse baştan kuruyor, hem de Rust ve Swift’ten esinlenerek. Yani artık sadece “şu satırda pointer var, dikkat” demekle kalmıyoruz.

Yıllardır.NET tarafında çalışan biri olarak şunu rahatça söyleyebilirim: bu değişiklik, nullable reference types’ın 2019’da yarattığı etkiye baya yakın duruyor. Hatta belki bir tık üstü. Çünkü mesele sadece sözdizimi değil, işin içinde bir sözleşme modeli var.

Lafı fazla dolandırmadan dalalım.

Önce şu “unsafe” meselesini hatırlayalım

C# 1.0’dan beri unsafe vardı, yani 2002’den beri. O günlerde mantık çok basitti: pointer kullanacaksan “ben ne yaptığımı biliyorum” diye el kaldırıyordun. Compiler da sana bakıp “tamam, ben karışmıyorum” diyordu.

Ama yıllar geçince tablo dağıldı biraz. System.Runtime.CompilerServices.Unsafe geldi, Marshal geldi, MemoryMarshal geldi… Bunların hepsi riskli işler yapıyordu ama garip şekilde çoğu zaman unsafe istemiyordu. Yani yük tamamen alışkanlığa kaldı; “iyi geliştirici zaten dikkat eder” kafası çalışıyordu.

Bence işin aslı şu: o yaklaşım 2010’larda idare ediyordu. Şimdi işe LLM’ler kod üretiyor, junior bir arkadaş Copilot’tan MemoryMarshal.Cast çekiyor ve ortada hiçbir kırmızı bayrak yok. Tehlike oradaydı zaten. Ben Logosoft’ta bir bankacılık projesinde buna benzer bir şeyi yaşamıştım; code review sırasında Unsafe.As<T>‘yi fark etmek için ya tecrübeli göz gerekiyordu ya da düzgün ayarlı bir analyzer (ikisi de her ekipte bulunmuyor maalesef).

Peki yeni model neyi değiştiriyor?

Kısaca şöyle: unsafe, artık sadece bir sözdizimi etiketi gibi davranmayacak; daha çok bir sözleşme işareti olacak. Yani “burada pointer var” demekten ziyade, “bu kodu çağıran tarafın bazı şeyleri garanti etmesi lazım” diyecek.

Bence, Rust bilenlere tanıdık gelecek bu yapı. Rust’taki unsafe fn, fonksiyonun içinde tehlikeli şeyler döndüğünü değil, fonksiyonu çağırmadan önce çağıranın sağlaması gereken invariant’lar olduğunu söylüyor. C# tarafı da aynı tarafa kayıyor gibi duruyor.

Birkaç temel fark var:

  • Yayılma (propagation): Bir unsafe metodu çağıran kod da ya kendi başına unsafe olacak ya da bir unsafe bloğunun içine girecek. Compiler bunu artık zorlayacak.
  • Kapsam genişlemesi: Sadece pointer içeren parçalar değil, compiler’ın güvenliğini doğrulayamadığı bütün alanlar. Mesela Unsafe, Marshal, span üzerinde tıp dönüşümleri… bunlar da işin içine giriyor.
  • Safety yorumları: Yeni bir // SAFETY:` tarzı geliyor. Bir `unsafe` bloğu açınca neden güvenli olduğunu yazmanız bekleniyor. Compiler bunu tek başına dayatmayacak ama analyzer’lar ve code review araçları bunu yakalayabilecek.

“unsafe artık bir sözdizimi türünü değil, bir sözleşme türünü işaretliyor — yetenekli bir geliştiricinin okuyup onaylaması gereken, compiler’ın doğrulayamadığı bir sözleşme.”

Peki pratikte nasıl görünecek?

Somut örnek iyi ölür diye düşündüm; aşağıya eski ve yeni yaklaşımı yan yana koydum:

// ESKİ MODEL (C# 1.0 — 15)
public Span<byte> GetBytes(int[] data)
{
// Marshal.UnsafeAddrOfPinnedArrayElement güvensiz
// ama unsafe işareti gerekmiyor — convention'a kalmış
return MemoryMarshal.AsBytes(data.AsSpan());
}
// YENİ MODEL (C# 16 önizleme)
public Span<byte> GetBytes(int[] data)
{
unsafe
{
// SAFETY: data dizisi method scope'unda canlı,
// pointer yaşam süresi span ile sınırlı,
// tip dönüşümü byte boyut hizalamasını korur.
return MemoryMarshal.AsBytes(data.AsSpan());
}
}

Şöyle söyleyeyim, Dikkat edin, fark küçük gibi duruyor ama etkisi başka. Eski kodda ortada uyarı falan yok; sanki sıradan güvenli API çağrısı yapıyormuşsunuz gibi görünüyor. Yeni modelde işe (belki yanilıyorum ama) hem açıkça bir `unsafe` bloğu var hem de neden güvenli olduğuna dair not düşülmüş durumda. Code review yapan kişi tek bakışta “buraya ekstra dikkat lazım” diyebiliyor. Python Agent Skills: Üç Yöntem, Tek Provider Se… yazımızda bu konuya da değinmiştik. Bu konuyla ilgili NL2SQL Gerçekten İşe Yarıyor mu? SQL MCP Server Notları yazımıza da göz atmanızı tavsiye ederim.

Bunu niye şimdi yapıyorlar? AI yüzünden mi?

Evet, bence büyük ölçüde öyle. Microsoft bloğunda hafifçe geçiliyor ama ben açık söyleyeyim: AI destekli kod üretimi manuel code review hızını çoktan solladı bile.

Daha geçen ay bir müşteride şuna benzer bir olay yaşadık: geliştirici Copilot’tan performans iyileştirmesi istemişti, Copilot da içinde >Unsafe.ReadUnaligned` olan bir çözüm önermişti (kod çalışıyor, testler yeşil, PR hazır). Eğer o gün ben PR'a bakmasaydım muhtemelen production'a inecekti; ARM tabanlı cihazda alignment sıkıntısı çıkarması da kuvvetle muhtemeldi. Visual Studio Plan Agent: Önce Düşün, Sonra Kodla yazımızda bu konuya da değinmiştik.

Sorun Copilot’un kötü olması değildi aslında. Sorun şu: tehlikeli kod ile sıradan kod arasında gözle görülür netlik yoktu. Yeni model olsaydı Copilot ya bunu `unsafe` bloğunda üretmek zorunda kalacaktı ya da derleyici suratına hata çarpacaktı — ikisi de fena değil hani.

Peki neden? Daha fazla bilgi için MCP Sunucuları İçin Yönetişim: .NET’e Yeni Toolkit Geldi yazımıza bakabilirsiniz. Cosmos Conf 2026: AI Çağında Veritabanı Nereye Gidiyor? yazımızda bu konuya da değinmiştik.

💡 Bilgi:

Türkiye’deki şirketler için ne anlama geliyor?

İtiraf edeyim,
Şimdi biraz frene basalım.
Buraya kadar anlattığım kısım Microsoft’un genel resmî.
Ama Türkiye’de kurumsal tarafta çalışan biri olarak şunu eklemek gerekiyor:
bu değişikliğin sahadaki etkisi biraz farklı hissedilecek.
Uzun cümle oldu ama önemli.
Bir yandan legacy sistemler var,
öbür yandan yeni servisler hızlı hızlı çıkıyor;
işte tam o aralıkta bu model baya işe yarayabilir.

İlk nokta şu:
Türk kurumsal yazılım dünyasında hâlâ.NET Framework 4.x üstünde yaşayan ciddi sistemler var.
Bankalar,
sigorta şirketleri,
telekom tarafı…
Bunlar C# 16’ya hop diye geçemez.
Ama yeni yazılan modüller ve mikroservislerde bu özellik baya değerli olabilir.
Bilhassa de BDDK ve EPDK gibi denetleyici kurumlara karşı güvenlik anlatırken
“memory-safety policy” göstermek artık boş checkbox olmaktan çıkabilir;
iş biraz daha somut hâle gelir.

Bunu biraz açayım.

İkinci nokta daha pratik:
KOBI ölçeğindeki yazılım evleri için bu özellik maliyet düşürücü olabilir.
Senior developer açığı malum zaten,
o yüzden junior ağırlıklı ekiplerde compiler’ın size
“dür bakalım burası riskli”
demesi code review süresini ciddi biçimde azaltabilir.
Ben kaba taslak hesap yaptığımda,
orta ölçekli projelerde güvenlik odaklı review süresinin yüzde 15-20’si kadar zaman kurtarabileceğini düşünüyorum;
%100 doğru olmayabilir ama saha hissi o yönde.
(buna dikkat edin)

Peki enterprise ile startup aynı mı davranmalı?

Senaryo Tavsiye
Büyük kurumsal (10+ servis) .NET 11 preview’da pilot bir mikroservis seçin Aşamalı,6-12 ay
Startup / Küçük ekip Yeni projelerde.NET
12 GA ile direkt opt-in
Tek seferde
Legacy Framework
4.x
Sadece yeni modüllerde değerlendirin Hibrit yaklaşım
Açık kaynak kütüphane Mümkün olduğunca erken adopt edin Sürüm bazlı

<>
<>

<>

Sıkça Sorulan Sorular

C# 16 unsafe modeli mevcut kodumu kırar mı?

Şunu fark ettim: Hayır, başlangıçta opt-in olacak. Yani projenize özel olarak açmadığınız — itiraz edebilirsiniz tabi — sürece her şey eskisi gibi çalışmaya devam ediyor. Nullable reference types’ta da böyleydi hani, aynı mantık. Ama açıkçası ileride default olabilir — o yüzden bence geçişi şimdiden planlamak mantıklı.

Yeni model performans kaybına neden ölür mu?

Runtime performansı açısından sıfır etki. Değişiklik tamamen compile-time’da kalıyor çünkü. unsafe bloğu IL seviyesinde herhangi bir ek kod üretmiyor, yani aslında sadece compiler’ın izin verdiği işlemlerin sınırlarını çiziyor.

SAFETY yorumlarını yazmak zorunda mıyım?

Teknik olarak compiler zorlamıyor, hayır. Ama hem code review hem de uzun vadeli bakım açısından şiddetle tavsiye ederim. Tecrübeme göre bu tür yorumları atlamak ileride ciddi baş ağrısına dönüşüyor. Analyzer’lar yorum eksikliğini uyarı olarak işaretleyebiliyor, takiminızın standardına göre bunu zorunlu hâle getirebilirsiniz.

Rust’taki unsafe ile aynı mı?

Felsefe olarak çok benzer, ama tam aynı değil. Mesela Rust’ta unsafe bloklar dilin sahip olduğu birçok kontrolü devre dışı bırakıyor. C#’ta işe CLR’ın garbage collector ve type safety mekanizmaları her durumda çalışmaya devam ediyor — bu önemli bir fark aslında. C# 16’daki unsafe, daha çok “compiler’ın doğrulayamadığı sözleşmeler” için bir işaretçi gibi düşünebilirsiniz.

Preview’ı nasıl deneyebilirim?

Bak şimdi,.NET 11 SDK preview’larını indirip csproj dosyanizda <LangVersion>preview</LangVersion>. Ilgili feature flag’i etkinleştirmeniz yeterli. GitHub’daki dotnet/roslyn deposunda örnek konfigürasyonlar da var, oradan bakmanızı öneririm.

Kaynaklar ve İleri Okuma

Şöyle söyleyeyim, Improving C# Memory Safety —.NET Blog (Richard Lander)

Tuhaf ama, dotnet/roslyn GitHub Deposu — Compiler Implementasyonu

C# Unsafe Code — Resmî Microsoft Dokümantasyonu

Bence, ONCD Technical Report on Memory Safety (2024)

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

← Onceki Yazi
MCP Sunucuları İçin Yönetişim: .NET'e Yeni Toolkit Geldi
Sonraki Yazi →
PowerShell macOS'ta Notarize Edildi: Gatekeeper Çilesi Bitti

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İçindekiler
← MCP Sunucuları İçin Yönetişim:...
PowerShell macOS’ta Nota... →