Bagikan melalui


Menggunakan Varians dalam Antarmuka untuk Koleksi Generik (C#)

Antarmuka kovarian memungkinkan metodenya untuk mengembalikan jenis yang lebih turunan daripada yang ditentukan dalam antarmuka. Antarmuka kontravarian memungkinkan metodenya menerima parameter dari jenis yang kurang turunan dibandingkan dengan yang ditentukan dalam antarmuka.

Dalam .NET Framework 4, beberapa antarmuka yang ada menjadi kovarian dan kontravarian. Ini termasuk IEnumerable<T> dan IComparable<T>. Ini memungkinkan Anda menggunakan kembali metode yang beroperasi dengan koleksi generik jenis dasar untuk koleksi jenis turunan.

Untuk daftar antarmuka varian di .NET, lihat Varians di Antarmuka Generik (C#).

Mengubah Koleksi Generik

Contoh berikut mengilustrasikan manfaat dukungan kovarians dalam IEnumerable<T> antarmuka. Metode PrintFullName ini menerima kumpulan jenis IEnumerable<Person> sebagai parameter. Namun, Anda dapat menggunakannya kembali untuk koleksi jenis IEnumerable<Employee> karena Employee mewarisi Person.

// 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);  
  
    }  
}  

Membandingkan Koleksi Generik

Contoh berikut mengilustrasikan manfaat dukungan kontravariansi di IEqualityComparer<T> antarmuka. Kelas PersonComparer menerapkan antarmuka IEqualityComparer<Person>. Namun, Anda dapat menggunakan kembali kelas ini untuk membandingkan urutan objek jenis Employee karena Employee mewarisi Person.

// 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);  
    }  
}  

Lihat juga