Covariance ve Contravariance: Generic Tipler Arası Dönüşüm

C# dilinde generic tipler kullanırken, bir List<Hayvan> değişkenine List<Köpek> atayabilir misin? Cevap çoğu zaman hayır. bu noktada covariance ve contravariance devreye girer, kalıtım ilişkisini generic parametrelere taşıyan mekanizmalar.

Covariance, türetilmiş bir tipi temel tipmiş gibi davranmanı sağlar. Yalnızca okuma (çıktı) işlemleri için güvenlidir.

1public interface IRepository<out T>
2{
3T GetItem();
4}
5
6public class Hayvan { }
7public class Köpek: Hayvan { }
8
9public class KöpekRepository: IRepository<Köpek>
10{
11public Köpek GetItem() => new Köpek();
12}
13
14var köpekRepo = new KöpekRepository();
15IRepository<Hayvan> hayvanRepo = köpekRepo; // Covariance sayesinde çalışır
16Hayvan sonuc = hayvanRepo.GetItem(); // Köpek döner, Hayvan olarak tutulur

Burada out anahtar sözcüğü covariance'ı etkinleştirir. GetItem() yalnızca tip döndürdüğü için, Köpek yerine Hayvan istemek güvenlidir.

Contravariance bunun tersidir. Temel tipi türetilmiş tipmiş gibi kullanmayı sağlar. Yalnızca yazma (girdi) işlemleri için güvenlidir.

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1public interface ILogger<in T>
2{
3void Log(T item);
4}
5
6public class UniversalLogger: ILogger<Hayvan>
7{
8public void Log(Hayvan item)
9{
10Console.WriteLine($"Hayvan logu: {item.GetType().Name}");
11}
12}
13
14var universalLogger = new UniversalLogger();
15ILogger<Köpek> köpekLogger = universalLogger; // Contravariance sayesinde çalışır
16köpekLogger.Log(new Köpek()); // Çıktı: Hayvan logu: Köpek

Burada in anahtar sözcüğü contravariance'ı etkinleştirir. Metot yalnızca parametre aldığı için, Köpek yerine Hayvan kabul eden logger güvenlidir.

Covariance ve contravariance olmadan, kalıtım ilişkisi generic parametrelerde kaybolur ve kod yeniden kullanımı azalır. out ve in ile bu ilişkiyi koruyup tür güvenliğini de sağlarsın.

Pratik bir kural: veri çıkıyor mu out (covariance), veri giriyor mu in (contravariance). Her ikisine de ihtiyaç varsa, variance kullanmadan düz generic yazarsın.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz