简体   繁体   English

为什么即使变量是引用类型,Equals和ReferenceEquals方法的结果也不同?

[英]Why do the results of the Equals and ReferenceEquals methods differ even though variables are reference types?

As per this msdn documentation 根据这个 msdn文档

If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method . 如果当前实例是引用类型,则Equals(Object)方法测试引用相等性,并且对Equals(Object)方法的调用等效于对ReferenceEquals方法的调用

then why does following code results in two different result of method calls Equals method returning True and ReferenceEquals method returning false, even though the obj and obj1 is reference type as IsClass property returns true. 那么为什么跟随代码导致两个不同的方法调用结果Equals方法返回True,ReferenceEquals方法返回false,即使objobj1是引用类型,因为IsClass属性返回true。

using System;

public class Program
{
    public static void Main()
    {
        var obj = new { a = 1, b = 1 };
        var obj1 = new { a = 1, b = 1 };

        Console.WriteLine("obj.IsClass: " + obj.GetType().IsClass);

        Console.WriteLine("object.ReferenceEquals(obj, obj1): " + object.ReferenceEquals(obj, obj1));

        Console.WriteLine("obj.Equals(obj1): " + obj.Equals(obj1));
    }
}

Output: 输出:

obj.IsClass: True obj.IsClass:是的

object.ReferenceEquals(obj, obj1): False object.ReferenceEquals(obj,obj1): False

obj.Equals(obj1): True obj.Equals(obj1): 是的

obj and obj1 refer to 2 different objects, so object.ReferenceEquals() will return false. objobj1引用2个不同的对象,因此object.ReferenceEquals()将返回false。

Equals() returns true, because the compiler implements Equals() for anonymous types. Equals()返回true,因为编译器为匿名类型实现了Equals() It will return true if all the properties of both objects have the same values. 如果两个对象的所有属性具有相同的值,它将返回true。

All anonymous types have an Equals override that works by: 所有匿名类型都具有Equals覆盖,其工作方式为:

  1. If the first object is null then return true if the second is null, false otherwise. 如果第一个对象为null,则返回true如果第二个为null,否则返回false
  2. If the second object is null, then return false . 如果第二个对象为null,则返回false
  3. If the two objects are of different types, return false (but all anonymous objects who have the same properties which are the same name for the same type in the same object are the same type). 如果两个对象具有不同的类型,则返回false (但是,对于同一对象中具有相同属性且同一类型的相同属性的所有匿名对象是相同类型)。
  4. Go through each of the properties, if calling Equals on the values the two objects have for that property is false , return false . 浏览每个属性,如果对两个对象对该属性的值调用Equalsfalse ,则返回false
  5. Return true. 回归真实。

(They also have a GetHashCode which works by combining GetHashCode calls on each property). (它们还有一个GetHashCode ,它通过在每个属性上组合GetHashCode调用来工作)。

If it wasn't for this, then GroupBy , Distinct , Union and similar couldn't work with anonymous properties, since each of those methods needs a concept of equality to work. 如果不是这样的话,那么GroupByDistinctUnion和类似的东西就无法使用匿名属性,因为每个方法都需要一个相等的概念才能工作。

ReferenceEquals works by returning true if the two objects are in fact the same object, false if they are not. 如果两个对象实际上是同一个对象,则ReferenceEquals返回true如果true则返回false

The default for a non-anonymous object is for Equals to return the same thing as ReferenceEquals . 非匿名对象的默认值是Equals返回与ReferenceEquals相同的内容。 If it was not anonymous, and something other than this was desired then the author would have provided an Equals override, and would have much greater flexibility in how they did so. 如果它不是匿名的,并且需要除此之外的其他内容,那么作者将提供Equals覆盖,并且在他们如何这样做时将具有更大的灵活性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM