C# 中 ==,Equals, ReferenceEquals三者的区别

时间:2022-09-02 16:16:29

ReferenceEquals

ReferenceEquals是Object类的一个静态方法,在任何时候都是比较引用是否相等

在比较如果比较的类型是值类型是,因为ReferenceEquals 的形参列表是Object类型所以在调用的时候存在一个装箱过程,

所以用来比较值类型是没有意义的,一直返回的是false

 

Equals

针对引用引用类型比较的是对象的引用地址,

针对值类型的话比较的是对象的值,

如果是自定义值类型如果要进行比较的话最好重写一下这个方法:

 1     public abstract class ValueType
 2     {
 3         [__DynamicallyInvokable, SecuritySafeCritical]
 4         public override bool Equals(object obj)
 5         {
 6             if (obj == null)
 7             {
 8                 return false;
 9             }
10             RuntimeType runtimeType = (RuntimeType)base.GetType();
11             if ((RuntimeType)obj.GetType() != runtimeType)
12             {
13                 return false;
14             }
15             if (ValueType.CanCompareBits(this))
16             {
17                 return ValueType.FastEqualsCheck(this, obj);
18             }
19             FieldInfo[] fields = runtimeType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
20             for (int i = 0; i < fields.Length; i++)
21             {
22                 object obj2 = ((RtFieldInfo)fields[i]).UnsafeGetValue(this);
23                 object obj3 = ((RtFieldInfo)fields[i]).UnsafeGetValue(obj);
24                 if (obj2 == null)
25                 {
26                     if (obj3 != null)
27                     {
28                         return false;
29                     }
30                 }
31                 else if (!obj2.Equals(obj3))
32                 {
33                     return false;
34                 }
35             }
36             return true;
37         }

可以看到默认的实现是使用了反射原理比较了两个值的所有字段

==

针对C#默认的值类型是比较的是对象的值,对于自定义值类型是没有默认的实现的

针对引用类型比较的是引用地址

 

Equals 和 == 运算符是可以进行重写覆盖的,所以在有些类的对象的表现可能和上述所说的可能表现的不一致