On the msdn page on contravariance, I find a rather interesting example that shows the "benefits of contravariance in IComparer"
First they use the rather odd base and derived classes:
public class Person { public string FirstName { get; set; } public string LastName { get; set; } } public class Employee : Person { }
I can already say that his bad example does not cause the class to ever just inherit the 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) { .. } }
The following is an example.
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 is - first of all, in this case Employee is an unnecessary class, its true that it can use PersonComparer for this situation, because it is really just a human class!
In the real world, however, Employee will have at least one new field, say a JobTitle . Given that it is pretty clear that when we want Distint employees to be needed, we need to consider this JobTitle field for comparison, and it’s pretty clear that a Contravariant Comparer, such as a face mapper, is not suitable for this job because it doesn’t can know no new members The employee identified.
Now, of course, any language can even be very strange, even if it is illogical for any situation, but in this case I think that too often it will not be useful for default behavior. In fact, it seems to me that we are a little violating type safety, when a method expects Employee comparisons, we can actually put a person or even an object comparator, and it compiles without problems. While it is difficult to imagine that our default scenario will refer to the Employee as an object ... or to the main Person.
So is this really good default contravariance for these interfaces?
EDIT: I understand what contravariance and covariance are. I ask why these interface comparisons have been modified to be contravariant by default.