我只是想知道为什么语言的设计师决定在匿名类型上实现Equals的方式类似于Equals在值类型上实现。这不是误导吗?
Equals
public class Person { public string Name { get; set; } public int Age { get; set; } } public static void ProofThatAnonymousTypesEqualsComparesBackingFields() { var personOne = new { Name = "Paweł", Age = 18 }; var personTwo = new { Name = "Paweł", Age = 18 }; Console.WriteLine(personOne == personTwo); // false Console.WriteLine(personOne.Equals(personTwo)); // true Console.WriteLine(Object.ReferenceEquals(personOne, personTwo)); // false var personaOne = new Person { Name = "Paweł", Age = 11 }; var personaTwo = new Person { Name = "Paweł", Age = 11 }; Console.WriteLine(personaOne == personaTwo); // false Console.WriteLine(personaOne.Equals(personaTwo)); // false Console.WriteLine(Object.ReferenceEquals(personaOne, personaTwo)); // false }
乍一看,所有打印的布尔值都应该为false。但是Equals当使用Persontype并使用匿名类型时,带有调用的行将返回不同的值。
Person
匿名类型实例是没有行为或身份的不可变数据值。参照比较它们没有多大意义。在这种情况下,我认为为它们进行结构相等比较是完全合理的。
如果要将比较行为切换为自定义方式(引用比较或不区分大小写),则可以使用Resharper将匿名类型转换为命名类。Resharper还可以生成平等成员。
这样做还有一个非常实际的原因:匿名类型在LINQ连接和分组中可以方便地用作哈希键。出于这个原因,他们需要语义正确Equals和GetHashCode实现。
GetHashCode