Giriş
Açıklaması şöyle
Covariance kalıtan sınıfın üst sınıf yerine kullanılabilmesi demek. Kavram kendi içinde covariant nesne atama ve covariant return type olarak ayrışmış durumda.
Covariance C# 4.0 ile geliyor ve array, delegate ve generic'lerle beraber kullanılıyor.
Dikkat!
Dikkat edilmesi gereken nokta covariant nesne atama adı üzerinde sadece reference tipler için kullanılır. Value tipler nesne olmadıkları için covariant nesne atama işlemine tabi tutulamazlar. Aşağıdaki kod int kullanıldığı derlenmez!
Grandfather'dan kalıtan Son sınıfımız olsun. Eskiden "Grandfather" listesi'ne "Son" listesi atanamıyordu!
Bazı sınıfların özellikleri şöyle
1. Array Sınıfı
Array covariant. Şöyle yaparız.
Delegate covariant. Şöyle yaparız.
ICollection covariant değil. Şu kod derlenmez
List covariant değil. Şöyle tanımlıdır.
Şu kod derlenmez.
Elimizde şöyle bir metod olsun
Listeyi çevirmek için şöyle yaparız. Bu aslında covariance değil. Yeni bir liste yaratıyor.
Açıklaması şöyle
Covariance: Enables you to use a more derived type than originally specified.
Covariance C# 4.0 ile geliyor ve array, delegate ve generic'lerle beraber kullanılıyor.
Dikkat!
Dikkat edilmesi gereken nokta covariant nesne atama adı üzerinde sadece reference tipler için kullanılır. Value tipler nesne olmadıkları için covariant nesne atama işlemine tabi tutulamazlar. Aşağıdaki kod int kullanıldığı derlenmez!
IEnumerable<int> intList = new List<int>();
IEnumerable<object> objList = intList;
Açıklaması şöyle.Covariance'tan Önceki ProblemVariance applies only to reference types; if you specify a value type for a variant type parameter, that type parameter is invariant for the resulting constructed type.
Grandfather'dan kalıtan Son sınıfımız olsun. Eskiden "Grandfather" listesi'ne "Son" listesi atanamıyordu!
//will throw exception prior to version 4.01
IEnumerable<GrandFather> fathers = new List<Son>();
DiğerBazı sınıfların özellikleri şöyle
1. Array Sınıfı
Array covariant. Şöyle yaparız.
// Array assignment works
Animal[] animals = new Giraffe[10];
2. Delegate SınıfıDelegate covariant. Şöyle yaparız.
Func<string> stringFactory = () => "always return this string";
Func<object> objectFactory = stringFactory; // Safe, allowed in C# 4
3. ICollection ArayüzüICollection covariant değil. Şu kod derlenmez
IEnumerable<Animal> x = ViewModelList; // ok
ICollection<Animal> y = ViewModelList; // not ok.
4. IEnumerable Arayüzü- Read-Only
Bu özelliklik C# 4.0 ile geliyor. IEnumerable covairant olduğu için covariant atama yapılabilir. Şöyle tanımlıdır. Buradaki out kelimesi covariant olduğunu belirtir.public interface IEnumerable<out T> : IEnumerable
Şöyle yaparız.IEnumerable<Animal> animals = new List<Giraffe>();
// Can't add a Lion to animals, as `IEnumerable<out T>` is a read-only interface.
Eğer istersek daha okunur olduğunu düşünüyorsak casting kodu da eklenebilir. Şöyle yaparız.// explicit casting
IEnumerable<Animal> animals = (IEnumerable<Animal>) new List<Giraffe>();
5. List SınıfıList covariant değil. Şöyle tanımlıdır.
public class List<T> : IList<T>, ... ...
Örnek Şu kod derlenmez.
List<Animal> animals = new List<Giraffe>();
Örnek Elimizde şöyle bir metod olsun
public Constructor (List<IData> data) { ... }
IData'dan kalıtan source sınıfımız olsun. Şu kod da derlenmez.var a = new Constructor (new List<source> ()); This is failed
ÇözümListeyi çevirmek için şöyle yaparız. Bu aslında covariance değil. Yeni bir liste yaratıyor.
List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = giraffes.Cast<Animal>().ToList();
Çözüm
Bu kod çözüm 1'e göre daha kötü. .Net 2.0 ile çalışıyorken kullanılmalı.Şöyle yaparız.
List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = new List<Animal>(giraffes.ToArray());
Hiç yorum yok:
Yorum Gönder