Bagikan melalui


Menggunakan Varians dalam Antarmuka untuk Kumpulan Generik (C#)

Antarmuka kovarian memungkinkan metodenya untuk mengembalikan lebih banyak jenis turunan daripada yang ditentukan dalam antarmuka. Antarmuka kontravarian memungkinkan metodenya untuk menerima parameter dari jenis turunan yang lebih sedikit daripada yang ditentukan dalam antarmuka.

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

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

Mengonversi Koleksi Generik

Contoh berikut menggambarkan keuntungan dukungan kovarians di antarmuka IEnumerable<T>. Metode PrintFullName menerima koleksi jenis IEnumerable<Person> sebagai parameter. Tetapi, 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 menggambarkan keuntungan dukungan kontravarian di antarmuka IEqualityComparer<T>. Kelas PersonComparer menerapkan antarmuka IEqualityComparer<Person>. Tetapi, Anda dapat menggunakan kembali kelas ini untuk membandingkan urutan objek berjenis 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