سؤال

ما معنى مفهومي "التباين" و"التناقض"؟

نظرا 2 فصول، حيوان و الفيل (الذي يرث من حيوان)، ما أفهمه هو أنك سوف تحصل على أخطاء وقت التشغيل إذا حاولت وضع Elephant في مجموعة من Animals، ويحدث هذا لأن Elephant "أكبر" (أكثر تحديدًا) من Animal.ولكن هل يمكنك وضع حيوان في مجموعة من الفيلة، لترى كيف يضمن الفيل أن يحتوي على خصائص الحيوان؟

هل كانت مفيدة؟

المحلول

لديك الأمر إلى الوراء.يمكنك إضافة فيل إلى مصفوفة حيوانات لأنه هو Animal، ومن المضمون الحصول على جميع الأساليب المطلوبة من الحيوان.لا يمكنك إضافة حيوان إلى مصفوفة الفيل لأنه يفعل ذلك لا يمتلك جميع الأساليب التي يجب أن يمتلكها الفيل.

مقالة ويكيبيديا عن التغاير والتباين لديه تفسير جيد لهذا:

ضمن نظام الكتابة في لغة البرمجة، يكون عامل التشغيل من الأنواع إلى الأنواع متغيرًا إذا حافظ على ترتيب الأنواع، الذي يرتب الأنواع من أنواع أكثر تحديدًا إلى أنواع أكثر عمومية؛وهو مخالف إذا عكس هذا الترتيب.إذا لم ينطبق أي من هذه، فالعامل ثابت.هذه المصطلحات تأتي من نظرية الفئة.

كما قلت أن نوع الفيل كان "أكبر"، وهذا ليس هو الحال.نوع الحيوان "أكبر" بمعنى أنه يتضمن أنواعًا أكثر تحديدًا، مثل الفيل والزرافة والأسد.

نصائح أخرى

قم بإلقاء نظرة على هذه النظرة العامة حول التباين والتباين في C# 4.0 ومعرفة ما إذا كان ذلك يساعد:

http://blogs.msdn.com/charlie/archive/2008/10/27/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx

يجب أن تحاول قراءة الصفحات 45-49 من تقديم .NET 4.0 مع Visual Studio 2010 الذي يتعامل مع هذا المثال بالضبط.حتى أنه يحتوي على بعض الصور الجميلة للأفيال.

النقطة الرئيسية التي يجب إخراجها هي القيام بذلك

var things = new List<IThing<IContent>> { new ConcreteThing() }

مع:

public class ConcreteThing : IThing<ConcreteContent>
{

}

أنت بحاجة إلى "الخروج" في تعريف الواجهة، والذي سيسمح بتعيين نماذج أكثر تحديدًا، ولكن يجب ضمان أن أي شيء تتم قراءته من IThing هو النوع الأكثر عمومية.

public interface IThing<out T> where T : IContent
{
}

enter image description here

public interface IGoOut<out T>
{
    T Func();
}
public interface IComeIn<in T>
{
    void Action(T obj);
}
public class GoOutClass<T>:IGoOut<T>
{
    public T Func()
    {
        return default(T);
    }
}

public class ComeInClass<T> : IComeIn<T>
{
    public void Action(T obj) {  }
}

==========================================================
object obj = null;
//Covariance Example [Array +  IEnumerable<T> +  IEnumerator<T>  +  IInterface<Out T>  +  Func<T>]
object[] array = (string[]) obj;
IEnumerable<object> enumerable = (IEnumerable<string>) obj;
IEnumerator<object> enumerator = (IEnumerator<string>)obj;
IGoOut<object> goOut = (GoOutClass<string>)obj;
Func<object> func = (Func<string>)obj;


//Contravariance Example[IInterface<in T>]
IComeIn<string> comeIn = (ComeInClass<object>) obj;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top