C# Covariance ve Contravariance

Merhaba arkadaşlar,

Bu yazımda birbirinden türemiş tiplerin koleksiyon ile kullanıldığında ve koleksiyon tiplerin farklılaştığı için birbirine atanamama sorununu ele alındığı Covariance (out) ve Contravariance (in) kavramlardan bahsedeceğim. out ve in anahtar sözcükleri dikkatinizi çekmiştir. şimdilik bunlar göz önünde dursun 🙂

İlk bu kavramları öğrendiğimde açıkçası kafam karışmıştı. Adım adım gittikten sonra bende oturmaya başladı diyebilirim. İlk başta Variance kelimesinin türkçe karşılığına bakalım. Variance kelimesinin Türkçe karşılığı değişim ve uyuşmazlık olarak karşımıza çıkıyor. Yani C# 4.0 dan önce koleksiyon tipleri farklılaştığına birbirine atanırken uyuşmazlık sorunu vardı diye düşünebiliriz. ( atanırken compiler error alınması gibi)

Daha sonra C# 2.0 ile birlikte gelen şablon tipler geliştirilmiştir. Yine aynı şekilde şablon tipli koleksiyonlar birbirinden türemiş tipler ile kullanımında atama olmuyordu ve C# 4.0 ile birlikte bu sorun çözüldü.

Nedir bu Covariance ve Contravariance olayı?

Covariance geniş türlerin (more derived) küçük türlere (less derived) dönüşümüdür. (string türünün obje türüne dönüşümü gibi düşünebilirsiniz). out T anahtar sözcüğü dikkatinizi çekmiştir. Bu kullanım output safe olarak adlandırılır. Aynı zamanda atama uyumunu korur.

Contravariance ise covariance tam tersi olarak küçük türlerin (less derived) geniş türlere (more derived) dönüşümüdür. ( object türünün string türüne dönüşümü gibi düşünebilirsiniz) in T anahtar sözcüğü dikkatinizi çekmiştir. Bu kullanım input safe olarak adlandırılır. Covariance tersine atama uyumunu korumaz.

Kafa karışıklığı: object türü string türüne göre daha az genişletmiştir bir türdür. Küçük tür derken bundan bahsediyoruz. Zaten C#'ta her şey objectir mantığı vardır.

Küçük türlerin (less derived) geniş türlere (more derived) atanması geniş türlerin küçük türlere atanması iyi hoş güzel peki nasıl ve ne demek bunlar. O zaman bunu örneklerle açıklamaya çalışalım.

Covariance ile başlayalım. out T anahtar sözciği ile bildirillir dedik, string türünün object türüne atanabilmesini sağlar dedik. O zaman IEnumerable<object> türünde parametre alan bir metodun IEnumerable<string> türünde referans atanabilmesi mümkün anlamı çıkıyor.

Contravariance ise in T anahtar sözcüğü ile bildirilir dedik, object türünün string türüne atanabilmesini sağlar dedik. O zaman object parametresi alan bir metot, string parametresi alan bir delegate’e atanabilmesi anlamına çıkıyor.

Delegate (Temsilci) Covariance

Covariance esas aldığı dönüşümler gibi burada da aynı şeyleri düşünebiliriz. Burada bilmemiz gereken tür dönüştürme özelliği metot group variance olarak adlandırılması. Temsilcilerde (delegate) covariance nasıl kullanıldığını bir örnekle açıklayalım.

Generic Delegate (temsilci) Covariance ve Contravariance

Covariance ve Controvariance delegate (temsilci) lerde kullanabliyoruz. in ve out anahtar sözcüğü kullanmadan bu işlemi yapmayı denediğimizde compiler bizi uyarıyor ve bu tür dönüşümünü yapamayacağımızı belirtiyor. O zaman buradan string -> object (covariance), object -> string dönüşümleri için in ve out anahtar sözcüklerini kullanmalıyız çıkarımı yapabiliriz.

String türünü object türüne atamasını yaprken out anahtar sözcüğü ile belirtmediğimiz için compiler çalışma zamanında bize kızdı. Delegate metodumuzu out anahtar sözcüğü ile bildirdiğimizde bu dönüşümü yapabileceğiz.

Aynı işlem Contravariance için geçerlidir. Açıkça delegate in anahtar sözcüğü ile belirtmediğim zaman daha küçük türleri (less derived) daha geniş türlere (mor derived) atayamayız.

Covariance ve Contravariance Arayüzlerde (Interface) Kullanımı

C# 4.0 ile birlikte birbirinden türeyen tipleri arayüzlerde artık kullanabiliyoruz. in ve out anahtar sözcüğü ile bildirilen şablon tipler yalnızca arayüz ve delegate’lerde kullanılabilir (şimdilik 🙂 )

Covariance arayüzlerde kullanımı aşağıdaki gibidir.

Covariance şablon (generic) tipli arayüz (interfacelerde) methodlarının geri dönüş parametresi olarak kullanılır, methodlara argüman olarak kullanılmaz.

Contravariance arayüzlerde kullanımı aşağıdaki gibidir.

Arayüzlü şablonda hem Covariance ve hem de Contravariance kullanabiliriz. Bunun için in ve out anahtar sözcüklerini birlikte kullanmalıyız

  • Sonuç olarak Covaraince atama uyumluluğunu korurken, Contravariance bunun tam tersini yapar.
  • in (Contravariance), out (Covariance) anahtar sözcüğü ile bildirilen şablon tipler ancak arayüz ve delegatelerde kullanılabilir. (şimdilik 🙂 )
  • Dönüşüm işlemi referans dönüşüm işlemi olmalıdır.

Bu yazımda Covariance ve Contravariance hakkında edindiğim bilgileri paylaşmaya çalıştım. Umarım faydalı olmuştur.

Bir sonraki yazımda görüşmek üzere 🙂

Kaynaklar:

Her Yönüyle C# 7.0, Sefer Algan, Pusula Yayincilik

https://docs.microsoft.com/tr-tr/dotnet/csharp/programming-guide/concepts/covariance-contravariance/

Leave a Comment