C# interface'lerinde collection dönüş tipleri: interface, view ve snapshot farkı
Bir metot IReadOnlyList<T> döndürdüğünde çağıran taraf yalnızca yazma yapamayacağını öğrenir; verinin bağımsız bir kopya mı, canlı bir view mı yoksa sabit bir rapor mu olduğunu öğrenmez. Makale, bildirilen yetenek ile sahiplik/yaşam süresi sözleşmesini ayırıp collection dönüş tiplerini bu iki katmana göre değerlendiriyor.
Kilit noktalar
- IReadOnlyList<T> yalnızca sayma ve konuma göre okuma yeteneği verir; immutable kaynak veya immutable element anlamına gelmez
- List<T>'yi dar bir interface üzerinden döndürmek yeni bir kopya oluşturmaz, diğer alias'lar değişikliği görmeye devam eder
- AsReadOnly() canlı bir view üretir: kaynaktaki değişiklik ve eklemeler sarmalayıcıdan görünür
- ToArray() shallow snapshot'tır; dış üyeler ayrılır, referans tipli elementlerin iç durumu paylaşılır
- Gerçekten kopuk bir yanıt için LINQ projeksiyonuyla değerleri yeni bir DTO'ya taşıyın
- Büyük sonuç kümelerinde tüm veriyi materialize etmek yerine sayfalanmış (bounded) yanıt döndürmeyi değerlendirin
C#'ta bir collection döndürmek iki ayrı katmanı kapsıyor: derleyicinin gördüğü bildirilmiş tip ve çağıranın veri üzerindeki sahipliği. Mutable bir List<T>'yi IReadOnlyList<T> olarak döndürmek yalnızca görünen metotları daraltır; aynı listeye başka bir referans hâlâ eleman ekleyebilir, dolayısıyla "read-only" imzası bağımsız depolamayı garanti etmez.
AsReadOnly() ile alınan sarmalayıcı kendi üzerinden yazmayı engeller ama kaynak listeyi izlemeye devam eder; bu, canlı bir view isteyen bileşenler için doğru, sabit rapor bekleyen çağıranlar için yanlıştır. ToArray() ile alınan kopya ise dış yapıyı ayırır, element nesnelerini ayırmaz: record'un init-only property'leri içindeki listeyi immutable yapmaz. Değişmeyen değerler gerekiyorsa çözüm, LINQ projeksiyonuyla değerleri yeni bir DTO'ya taşımak. Snapshot alırken eşzamanlı yazma varsa koordinasyon (locking) şart; kopya sonrası kilit kurmak tutarlılık sağlamaz.
Gerçek dünyada kullanımı
- Sipariş listesi döndüren bir API'de ekranın canlı view, arka plandaki export işinin ise sabit snapshot istemesi
- Cache'lenen bir referans listesinin, sahibi nesnenin yaşam süresi bitince anlamsız hale gelmesi
- Rapor endpoint'inin sayaç ve sıralama garantisi vermesi gerektiğinde shallow kopyanın yetersiz kalması
- Çok thread'li bir writer varken tutarlı yanıt üretmek için okuma/yazma koordinasyonu gereken arka plan worker'ı
Neden önemli
Dönüş tipi seçimi, çağıranın neyi ne kadar süreyle güvenle kullanabileceğini belirler; yanlış varsayım, üretimde sessizce değişen veya yarısı eski verilerle dolu yanıtlara yol açar.