C#中Equality和Identity浅析

2019-12-26 11:31:12于丽
易采站长站为您分析C#中Equality和Identity浅析,本文先是讲解了Equality和Identity的定义,同时讲解了判断两个对象等价性的4种方法,需要的朋友可以参考下    

CLR提供了可以区分类型的Equality 和Identity能力。

Equality:如果两个对象是相同的类型,并且它们各自带有相同和等值的属性。(They are instances of the same type and if each of the fields in one object matches the values of the fields in the other object)

Equality必须满足三个必要条件:reflexive, symmetrics, and transitive 
reflexive: 自身相等,及a==a 是永远成立的; 
symmetrics: 对象性,及a==b成立那么b==a 也成立; 
transitive: 传递性,及a==b, b==c成立那么a==c 也成立。

Identity:两个对象必须相等(意味着他们共享同一块内存区域)(The two objects have the same values. – Two objects are identical if they share an address in memory)

CLR提供了至少四种方法来判断两个对象的等价性:

1.Public static bool ReferenceEquals(object left, object right);
2.Public static bool Equals(object left, object right);
3.Public virtual bool Equals(object right);
4.Public static bool operator==(MyClass left, MyClass right);

ReferenceEquals方法总是用来判断两个对象的Identity的,不管是针对值类型还是引用类型。所以针对值类型,调用该方法总是会返回false,因为值类型作为这个方法的参数时会进行装箱操作。

静态的Equals方法提供了判断两个对象的Equality能力,在其实现的内部,调用了上述第三个虚拟的Equals方法。和ReferenceEquals一样,它们已经具备从底层判断两个对象的能力,我们从来不会覆写这两个方法。

实例Equals方法也是用来区分两个对象的Equality的。

对于引用类型的对象,它和ReferenceEquals方法几乎是一样的。(因为判断两个引用类型是否的Equality往往从Identity上就可以区分)

而值类型的对象,我们不仅要判断他们具有相同的对象类型,还要判断他们的值相等。值类型从System.ValueType继承而来,ValueType已经重写了Object.Equals()方法,本来已经可以用来满足这些要求的。但是ValueType.Equals()方法不是很有效,因为它必须要通过反射,在不知道具体的派生类型中,完成对它们所含有成员变量的值的比较。因此,建议在我们实现一个值类型的数据结构时,同时重写ValueType.Equals()方法。