Varyans, yalnızca güvenli bir şekilde desteklenecek - aslında, CLR'nin zaten sahip olduğu yetenekler kullanılarak. Bu nedenle, a'yı List<Banana>bir List<Fruit>(veya her neyse) olarak kullanmaya çalışma kitabında verdiğim örnekler hala işe yaramayacak - ancak diğer birkaç senaryo işe yarayacak.
İlk olarak, yalnızca arayüzler ve temsilciler için desteklenecektir.
İkinci olarak, arayüz / temsilcinin yazarının tip parametrelerini in(kontravans için) veya out(kovaryans için ) olarak dekore etmesini gerektirir . En bariz örnek, IEnumerable<T>yalnızca ondan değer "çıkarmanıza" izin verendir - yenilerini eklemenize izin vermez. Bu olacak IEnumerable<out T>. Bu, tür güvenliğine hiç zarar vermez, ancak örneğin IEnumerable<string>return IEnumerable<object>için bildirilen bir yöntemden bir döndürmenize izin verir .
Contravariance, arayüzleri kullanmak için somut örnekler vermek daha zordur, ancak bir delege ile kolaydır. Düşünün Action<T>- bu sadece bir Tparametre alan bir yöntemi temsil eder . Sorunsuz dönüştürmek bir kullanabilmek için güzel olurdu Action<object>bir şekilde Action<string>bir alan herhangi bir yöntemle - objectparametre bir ile sunulan ne zaman cezası olacak stringyerine. Elbette, C # 2 zaten bir dereceye kadar delegelerin kovaryansına ve kontravansına sahiptir, ancak bir delege türünden diğerine gerçek bir dönüşüm yoluyla (yeni bir örnek oluşturma) - örnekler için bkz. P141-144. C # 4 bunu daha genel hale getirecek ve (inanıyorum) dönüşüm için yeni bir örnek oluşturmaktan kaçınacaktır. (Bunun yerine bir referans dönüştürme olacaktır.)
Umarım bu biraz açıklığa kavuşur - mantıklı değilse lütfen bana bildirin!