On the msdn page on contravariance I find a quite interesting example that shows "benefits of contravariance in IComparer"
First they use a fairly odd base & derived classes:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Employee : Person { }
I can already say that its a bad example cause no class ever just inherits a base class without adding at least a little something of its own.
Then they create a simple IEqualityComparer class
class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
..
}
public int GetHashCode(Person person)
{
..
}
}
Next the example in question goes.
List<Employee> employees = new List<Employee> {
new Employee() {FirstName = "Michael", LastName = "Alexander"},
new Employee() {FirstName = "Jeff", LastName = "Price"}
};
IEnumerable<Employee> noduplicates =
employees.Distinct<Employee>(new PersonComparer());
Now my question - first of all in this case Employee is an unneeded class, its true that it can use PersonComparer for this situation because it is in fact just a person class!
In real world however Employee
will have at least one new field, lets say a JobTitle
. Given that its pretty clear that when we want distint Employees we would need to take that JobTitle field in mind for comparison, and its pretty clear that Contravariant Comparer such as person comparer isn't suited for that job, cause it cannot know any new members Employee has defined.
Now of course any language feature even a very odd one could have its uses, even if its illogical for some situation, but in this case I think it won't be useful far too often to be a default behavior. In fact it appears to me as we are breaking type safety a little bit, when a method expects a Employee comparer we can in fact put in a person or even object comparer and it will compile with no problems. While its hard to imagine our default scenario would be to treat Employee like an object..or basic Person.
So is it really a good contravariance for default for those interfaces?
EDIT: I understand what contravariance and covariance is. I am asking why those comparing interfaces were changed to be contravariant on default.