مشاركة عبر


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

الواجهة الطردية تسمح لطرقها أن ترجع اشتقاق أنواع أكثر من تلك المحددة في الواجهة. واجهة contravariant تسمح للأساليب الخاصة به إلى قبول معلمات الأنواع المشتقة أقل من تلك المحددة في الواجهة.

في ".NET Framework 4،" الواجهات الموجودة تصبح طردية و contravariant . تتضمن هذه IEnumerable<T> و IComparable<T>. يتيح لك ذلك لإعادة إستخدام الأساليب التي تعمل مع مجموعات عامة أنواع أساسية لمجموعات الأنواع المشتقة.

للحصول على قائمة الواجهات متغير في .NET Framework راجع الالفرق في الواجهات العامة (C# و Visual Basic).

تحويل المجموعات العامة

يوضح المثال التالي فوائد دعم التباين المشترك في الواجهة IEnumerable<T> . الأسلوب PrintFullName يقبل مجموعة من IEnumerable<Person> نوع ( IEnumerable(Of Person) في Visual Basic) كـ المعلمة. ومع ذلك، يمكنك إعادة إستخدامه لمجموعة من نوع IEnumerable<Employee> ( IEnumerable(Of Person) في Visual Basic) لأن Employee يرث Person.

' Simple hierarchy of classes.
Public Class Person
    Public Property FirstName As String
    Public Property LastName As String
End Class

Public Class Employee
    Inherits Person
End Class

' The method has a parameter of the IEnumerable(Of Person) type.
Public Sub PrintFullName(ByVal persons As IEnumerable(Of Person))
    For Each person As Person In persons
        Console.WriteLine(
            "Name: " & person.FirstName & " " & person.LastName)
    Next
End Sub

Sub Main()
    Dim employees As IEnumerable(Of Employee) = New List(Of Employee)

    ' You can pass IEnumerable(Of Employee), 
    ' although the method expects IEnumerable(Of Person).

    PrintFullName(employees)

End Sub
// Simple hierarchy of classes.
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person { }

class Program
{
    // The method has a parameter of the IEnumerable<Person> type.
    public static void PrintFullName(IEnumerable<Person> persons)
    {
        foreach (Person person in persons)
        {
            Console.WriteLine("Name: {0} {1}",
            person.FirstName, person.LastName);
        }
    }

    public static void Test()
    {
        IEnumerable<Employee> employees = new List<Employee>();

        // You can pass IEnumerable<Employee>, 
        // although the method expects IEnumerable<Person>.

        PrintFullName(employees);

    }
}

مقارنة مجموعات عامة

يوضح المثال التالي فوائد دعم contravariance في الواجهة IComparer<T> . الفئة PersonComparer تتطلب الواجهة IComparer<Person> ( IComparer(Of Person) في Visual Basic). ومع ذلك، يمكنك إعادة إستخدام هذه لمقارنة تسلسل الكائنات من نوع Employee اكتب لأن Employee يرث Person.

' Simple hierarhcy of classes.
Public Class Person
    Public Property FirstName As String
    Public Property LastName As String
End Class

Public Class Employee
    Inherits Person
End Class
' The custom comparer for the Person type
' with standard implementations of Equals()
' and GetHashCode() methods.
Class PersonComparer
    Implements IEqualityComparer(Of Person)

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

        If x Is y Then Return True
        If x Is Nothing OrElse y Is Nothing Then Return False
        Return (x.FirstName = y.FirstName) AndAlso
            (x.LastName = y.LastName)
    End Function
    Public Function GetHashCode1(
        ByVal person As Person) As Integer _
        Implements IEqualityComparer(Of Person).GetHashCode

        If person Is Nothing Then Return 0
        Dim hashFirstName =
            If(person.FirstName Is Nothing,
            0, person.FirstName.GetHashCode())
        Dim hashLastName = person.LastName.GetHashCode()
        Return hashFirstName Xor hashLastName
    End Function
End Class

Sub Main()
    Dim employees = New List(Of Employee) From {
        New Employee With {.FirstName = "Michael", .LastName = "Alexander"},
        New Employee With {.FirstName = "Jeff", .LastName = "Price"}
    }

    ' You can pass PersonComparer, 
    ' which implements IEqualityComparer(Of Person),
    ' although the method expects IEqualityComparer(Of Employee)

    Dim noduplicates As IEnumerable(Of Employee) = employees.Distinct(New PersonComparer())

    For Each employee In noduplicates
        Console.WriteLine(employee.FirstName & " " & employee.LastName)
    Next
End Sub
// Simple hierarchy of classes.
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person { }

// The custom comparer for the Person type
// with standard implementations of Equals()
// and GetHashCode() methods.
class PersonComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {            
        if (Object.ReferenceEquals(x, y)) return true;
        if (Object.ReferenceEquals(x, null) ||
            Object.ReferenceEquals(y, null))
            return false;            
        return x.FirstName == y.FirstName && x.LastName == y.LastName;
    }
    public int GetHashCode(Person person)
    {
        if (Object.ReferenceEquals(person, null)) return 0;
        int hashFirstName = person.FirstName == null
            ? 0 : person.FirstName.GetHashCode();
        int hashLastName = person.LastName.GetHashCode();
        return hashFirstName ^ hashLastName;
    }
}

class Program
{

    public static void Test()
    {
        List<Employee> employees = new List<Employee> {
               new Employee() {FirstName = "Michael", LastName = "Alexander"},
               new Employee() {FirstName = "Jeff", LastName = "Price"}
            };

        // You can pass PersonComparer, 
        // which implements IEqualityComparer<Person>,
        // although the method expects IEqualityComparer<Employee>.

        IEnumerable<Employee> noduplicates =
            employees.Distinct<Employee>(new PersonComparer());

        foreach (var employee in noduplicates)
            Console.WriteLine(employee.FirstName + " " + employee.LastName);
    }
}

راجع أيضًا:

المبادئ

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