在有关逆变的msdn 页面上,我发现了一个非常有趣的示例,它显示了“IComparer 中逆变的好处”
首先,他们使用了一个相当奇怪的基类和派生类:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Employee : Person { }
我已经可以说这是一个不好的例子,因为没有一个类只是继承一个基类而不添加至少一点它自己的东西。
然后他们创建了一个简单的 IEqualityComparer 类
class PersonComparer : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
..
}
public int GetHashCode(Person person)
{
..
}
}
接下来是有问题的示例。
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());
现在我的问题 - 首先在这种情况下 Employee 是一个不需要的类,它确实可以在这种情况下使用 PersonComparer 因为它实际上只是一个人类!
然而,在现实世界中Employee
,至少会有一个新领域,比如说JobTitle
. 鉴于很明显,当我们想要区分员工时,我们需要考虑 JobTitle 字段进行比较,并且很明显,逆变比较器(例如人员比较器)不适合该工作,因为它不知道任何新成员员工已定义。
当然,任何语言特性,即使是一个非常奇怪的特性,都可以有它的用途,即使它在某些情况下是不合逻辑的,但在这种情况下,我认为它不会太频繁地成为默认行为。事实上,在我看来,因为我们有点破坏类型安全,当一个方法需要一个 Employee 比较器时,我们实际上可以放入一个人甚至对象比较器,它会毫无问题地编译。虽然很难想象我们的默认方案是将 Employee 视为对象..或基本 Person。
那么这些接口的默认逆变器真的是一个很好的逆变器吗?
编辑:我明白什么是逆变和协方差。我在问为什么那些比较接口被更改为默认逆变。