Genel Koleksiyonlar için Arabirimlerde Varyans Kullanma (C#)
Kovarant arabirim, yöntemlerinin arabirimde belirtilenlerden daha fazla türetilmiş tür döndürmesine olanak tanır. Değişken karşıtı arabirim, yöntemlerinin arabirimde belirtilenlerden daha az türetilmiş türlerdeki parametreleri kabul etmesine olanak tanır.
.NET Framework 4'te çeşitli mevcut arabirimler birlikte değişken ve değişkensiz hale geldi. Bunlar ve IComparable<T>içerirIEnumerable<T>. Bu, türetilmiş tür koleksiyonları için genel temel tür koleksiyonlarıyla çalışan yöntemleri yeniden kullanmanıza olanak tanır.
.NET'teki değişken arabirimlerin listesi için bkz . Genel Arabirimlerde Varyans (C#).
Genel Koleksiyonları Dönüştürme
Aşağıdaki örnek, arabirimdeki kovaryans desteğinin IEnumerable<T> avantajlarını göstermektedir. yöntemi, PrintFullName
türündeki IEnumerable<Person>
bir koleksiyonu parametre olarak kabul eder. Ancak, devraldığı Person
için bunu türündeki IEnumerable<Employee>
Employee
bir koleksiyon için yeniden kullanabilirsiniz.
// 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);
}
}
Genel Koleksiyonları Karşılaştırma
Aşağıdaki örnek, arabirimdeki değişken karşıtı desteğin IEqualityComparer<T> avantajlarını göstermektedir. PersonComparer
sınıfı, IEqualityComparer<Person>
arabirimini uygular. Ancak, devraldığından Person
türündeki bir nesne dizisini Employee
Employee
karşılaştırmak için bu sınıfı yeniden kullanabilirsiniz.
// 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);
}
}