مشاركة عبر


الالفرق في الواجهات العامة (C# و Visual Basic)

4 .NET Framework يقدم الدعم الالفرق العديد من الواجهات العامة الموجودة. يتيح دعم الالفرق التحويل الضمني الفئات التي تقوم بتطبيق هذه الواجهات. الواجهات التالية متغيرة الآن:

التباين المشترك يصرح أسلوب لجعله يحتوي نوع الإرجاع الأكثر اشتقاق من المعرف بواسطة نوع معلمة عام للواجهة. لتوضيح ميزة التباين خذ بعين الاعتبار هذه الواجهات العامة: IEnumerable<Object> و IEnumerable<String> IEnumerable(Of Object) و IEnumerable(Of String)في Visual Basic . IEnumerable<String>( IEnumerable(Of String)في Visual Basic) الواجهة لا ترث واجهة IEnumerable<Object>( IEnumerable(Of Object)في Visual Basic). ومع ذلك، يرث نوع StringالنوعObject، وفي بعض الحالات قد تحتاج إلى تعيين الكائنات هذه الواجهات إلى بعضها البعض. يظهر هذا في التعليمات البرمجية التالية.

Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;

في الإصدارات السابقة من برنامج .NET Framework يسبب هذه التعليمة البرمجية على خطأ في التحويل برمجي في C# و في Visual Basic مع Option Strict On. ولكن الآن يمكنك إستخدام stringsبدلاً من objects، كما هو موضح في المثال السابق، لأن الواجهة IEnumerable<T> طردية.

Contravariance يسمح لأساليب الواجهات باحتواء أنواع وسيطة أقل اشتقاقاً من المحددة من قبل المعلمات العامة. لتوضيح contravariance ، قم بافتراض أنك قمت بإنشاء فئة BaseComparerلمقارنة مثيلات الفئة BaseClass. الفئة BaseComparer تتطلب الواجهة IEqualityComparer<BaseClass> ( IEqualityComparer(Of BaseClass) في Visual Basic). لأن الواجهةIEqualityComparer<T> هي contravariant الآن, يمكنك إستخدام BaseComparerليقارن مثيلات الفئات التي ترث الفئة BaseClass. يظهر هذا في التعليمات البرمجية التالية.

' Simple hierarchy of classes.
Class BaseClass
End Class

Class DerivedClass
    Inherits BaseClass
End Class

' Comparer class.
Class BaseComparer
    Implements IEqualityComparer(Of BaseClass)

    Public Function Equals1(ByVal x As BaseClass,
                            ByVal y As BaseClass) As Boolean _
                            Implements IEqualityComparer(Of BaseClass).Equals
        Return (x.Equals(y))
    End Function

    Public Function GetHashCode1(ByVal obj As BaseClass) As Integer _
        Implements IEqualityComparer(Of BaseClass).GetHashCode
        Return obj.GetHashCode
    End Function
End Class
Sub Test()
    Dim baseComparer As IEqualityComparer(Of BaseClass) = New BaseComparer
    ' Implicit conversion of IEqualityComparer(Of BaseClass) to 
    ' IEqualityComparer(Of DerivedClass).
    Dim childComparer As IEqualityComparer(Of DerivedClass) = baseComparer
End Sub
// Simple hierarchy of classes.
class BaseClass { }
class DerivedClass : BaseClass { }

// Comparer class.
class BaseComparer : IEqualityComparer<BaseClass> 
{
    public int GetHashCode(BaseClass baseInstance)
    {
        return baseInstance.GetHashCode();
    }
    public bool Equals(BaseClass x, BaseClass y)
    {
        return x == y;
    }
}
class Program
{
    static void Test()
    {
        IEqualityComparer<BaseClass> baseComparer = new BaseComparer();

        // Implicit conversion of IEqualityComparer<BaseClass> to 
        // IEqualityComparer<DerivedClass>.
        IEqualityComparer<DerivedClass> childComparer = baseComparer;
    }
}

للحصول على أمثلة أخرى، انظر استخدام الالفرق في الواجهات و المجموعات العامة (C# و Visual Basic) .

يتم اعتماد الالفرق في الواجهات عامة أنواع المرجع فقط. لا تعتمد أنواع القيم الالفرق. على سبيل المثال، IEnumerable<int>( IEnumerable(Of Integer)في Visual Basic) لا يمكن تحويله ضمنيًا إلى IEnumerable<object>أو IEnumerable(Of Object)( أو في Visual Basic) ، لأن العدد الصحيح هو نوع القيمة.

Dim integers As IEnumerable(Of Integer) = New List(Of Integer)
' The following statement generates a compiler error
' with Option Strict On, because Integer is a value type.
' Dim objects As IEnumerable(Of Object) = integers
IEnumerable<int> integers = new List<int>();
// The following statement generates a compiler errror,
// because int is a value type.
// IEnumerable<Object> objects = integers;

من المهم أيضًا تذكر أن تكون الفئات التي تقوم بتنفيذ واجهات المتغير تظل ثابتة. على سبيل المثال، على الرغم من أن List<T>تثبت الواجهة الطردية IEnumerable<T>، لا يمكنك التحويل ضمنيًا List<Object>إلى List<String>( List(Of Object)إلى List(Of String)في Visual Basic). يتم توضيح هذا الإستخدام في المثال التالي.

' The following statement generates a compiler error
' because classes are invariant.
' Dim list As List(Of Object) = New List(Of String)

' You can use the interface object instead.
Dim listObjects As IEnumerable(Of Object) = New List(Of String)
// The following line generates a compiler error
// because classes are invariant.
// List<Object> list = new List<String>();

// You can use the interface object instead.
IEnumerable<Object> listObjects = new List<String>();

راجع أيضًا:

المرجع

استخدام الالفرق في الواجهات و المجموعات العامة (C# و Visual Basic)

المبادئ

واجهات عام

الفرق في المفوضون (C# و Visual Basic)

موارد أخرى

إنشاء متغير واجهات عام (C# و Visual Basic)