سؤال

لماذا، مع وجود قيد عام على معلمة النوع T من الفئة P من "يجب أن ترث من A"، تنجح المكالمة الأولى ولكن تفشل المكالمة الثانية مع خطأ تحويل النوع المفصل في التعليق:

abstract class A { }

static class S
{
    public static void DoFirst(A argument) { }
    public static void DoSecond(ICollection<A> argument) { }
}

static class P<T>
    where T : A, new()
{
    static void Do()
    {
        S.DoFirst(new T());             // this call is OK

        S.DoSecond(new List<T>());      // this call won't compile with:

        /* cannot convert from 'System.Collections.Generic.List<T>'
           to 'System.Collections.Generic.ICollection<A>' */
    }
}

ألا ينبغي أن يضمن القيد العام ذلك List<T> يكون بالفعل ICollection<A>?

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

المحلول

وهذا مثال على عدم C # الصورة من التغاير على الأنواع العامة (C # لا دعم مجموعة التغاير). C # 4 ستضيف هذه الميزة على أنواع واجهة، وكذلك سيتم تحديث عدة أنواع اجهة BCL لدعم أنها كذلك.

C # 4.0: التغاير و Contravariance :

<اقتباس فقرة>   

في هذا المقال سأحاول لتغطية واحدة   من الابتكارات C # 4.0. واحدة من   الميزات الجديدة هي التغاير و   contravariance على المعلمات النوع الذي   ويدعم الآن مندوبون عام   واجهات عامة. اسمحوا الأول   ترى ماذا تعني هذه الكلمات:)

نصائح أخرى

والقيد ليس له أي تأثير على المشكلة. المسألة هي ان كنت تمرير قائمة في معلمة يتطلب ICollection - C # لا يدعم التغاير لذلك تحتاج إلى يلقي صراحة قائمة إلى ICollection:

S.DoSecond((ICollection<A>) new List<T>());      // this call will be happy

لقد قمت بكتابة المعلمة DoSecond بقوة كنوع ICollection<A>.على الرغم من حقيقة أن T من النوع A، إلا أنه لا يوجد في وقت الترجمة ضمني يتم الإرسال بين القائمة<T> وIColction<A>.ستحتاج إما إلى إنشاء القائمة وإرسالها إلى ICollection<A> عند الاتصال بـ DoSecond، أو جعل DoSecond طريقة عامة بحد ذاتها.

ملحوظة:يجب دعم هذا النوع من التمثيل الضمني في الإصدار C# 4.0، والذي سيوفر تباينًا مشتركًا/تناقضًا محسّنًا كثيرًا مقارنة بما يقدمه الإصدار C# 3.0.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top