تدعم كل من C# و CLR السماح بعمل covariance و contra-variance لانواع الرفرنس عند ربط ميثود ما إلى delegate .
تعني Covariance أنه يمكن لميثود ما أن ترجع نوع مشتق من النوع المرجع للdelegate , بينما نعني بالContra-variance أنه يمكن لميثود أن تأخذ باراميتر يكون نوعه base لنوع الباراميتر للdelegate .
فلنفترض أنه يوجد لدينا الdelegate التالي :
delegate Object MyCallback(FileStream s);
فمن الممكن انشاء instance لهذا النوع من الdelegate يؤشر على ميثود يكون شكلها كالاتي :
String SomeMethod(Stream s);
النوع المرجع لهذه الميثود هو String والذي هو عبارة عن نوع مشتق من النوع المرجع للdelegate الذي هو object لذلك الcovariance موجودة هنا .
ولأن نوع الباراميتر لهذه الميثود هو Stream وهو الbase class لنوع الباراميتر للdelegate والذي هو FileStream لذلك الcontra-variance موجودة هنا ايضاً .
يجب أن تعلم أن الcovariance و الcontra-variance مدعومة فقط لانواع الرفرنس وليس انواع الvalue أو الvoid . فمثلاً لا يمكنك ربط الميثود التالية مع الdelegate :
Int32 SomeOtherMethod(Stream s);
فالنوع المرجع لهذه الميثود هو Int32 وهو مشتق من النوع المرجع للdelegate والذي هو object لكن المشكلة Int32 هي من نوع value وليس رفرنس لذلك لا يسمح بالcovariance هنا .
من الواضح أن سبب منع انواع value و void من استعمال الcovariance و الcontra-variance هو تركيب الذاكرة المتغير لهذه الأنواع . اما انواع رفرنس فتركيب الذاكرة لها هو pointer دائماً .
لذلك اذا حاولت استعمال الcovariance و الcontra-variance مع انواع value أو void فسوف يعطيك الكومبايلر خطأ أن هذه الأنواع لا تدعم هذا الأمر .
http://msdn.microsoft.com/en-us/library/ms173174(VS.80).aspx
عبد العظيم بخاري
http://www.el-bukhari.com/2010/11/covariance-contra-variance-4.html