Преимущества контравариантности в интерфейсах IComparer и IEqualityComparer

На странице msdn , посвященной контравариантности, я нашел довольно интересный пример, который показывает «преимущества контравариантности в IComparer»

Сначала они используют довольно странные базовые и производные классы:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person { }

Я уже могу сказать, что это плохой пример, потому что ни один класс никогда не наследует базовый класс, не добавляя хотя бы немного своего собственного.

Затем они создают простой класс IEqualityComparer

class PersonComparer : IEqualityComparer
{
    public bool Equals(Person x, Person y)
    {            
        ..
    }
    public int GetHashCode(Person person)
    {
       ..
    }
}

Далее идет рассматриваемый пример.

List employees = new List {
               new Employee() {FirstName = "Michael", LastName = "Alexander"},
               new Employee() {FirstName = "Jeff", LastName = "Price"}
            };

IEnumerable noduplicates = 
employees.Distinct(new PersonComparer());

Теперь мой вопрос - прежде всего, в этом случае Employee - ненужный класс, это правда, что он может использовать PersonComparer для этой ситуации, потому что на самом деле это просто класс человека!

Однако в реальном мире Сотрудник будет иметь по крайней мере одно новое поле, скажем, JobTitle . Учитывая, что довольно ясно, что когда нам нужны отдельные сотрудники, нам нужно будет учитывать это поле JobTitle для сравнения, и довольно ясно, что Contravariant Comparer, например, сравнение людей, не подходит для этой работы, потому что он не может знать никаких новых членов Сотрудник определил.

Конечно, любая языковая функция, даже очень странная, может найти свое применение, даже если она нелогична для некоторых ситуаций, но в данном случае я думаю, что она не будет полезна слишком часто, чтобы быть поведением по умолчанию. На самом деле мне кажется, что, поскольку мы немного нарушаем безопасность типов, когда метод ожидает компаратор Employee, мы фактически можем добавить человека или даже компаратор объектов, и он будет компилироваться без проблем. Хотя трудно представить, что наш сценарий по умолчанию будет относиться к Employee как к объекту ... или простому человеку.

Так действительно ли это хорошая контравариантность по умолчанию для этих интерфейсов?

EDIT: Я понимаю, что такое контравариантность а ковариация есть. Я спрашиваю, почему эти сравнивающие интерфейсы были изменены на контравариантные по умолчанию.

5
задан Valentin Kuzub 22 June 2011 в 03:08
поделиться