CLR提供了可以区分范例的Equality 和Identity才能。
l 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 也建立。
l 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一样,它们曾经具有从底层判别两个工具的才能,ag真人历来不会覆写这两个办法。
实例Equals办法也是用来区分两个工具的Equality的。
l 关于援用范例的工具,它和ReferenceEquals办法简直是一样的。(由于判别两个援用范例能否的Equality每每从Identity上就可以区分)
l 而值范例的工具,ag真人不但要判别他们具有相反的工具范例,还要判别他们的值相称。值范例从System.ValueType承继而来,ValueType曾经重写了Object.Equals()办法,原本曾经可以用来满意这些要求的。但ValueType.Equals()办法不是很无效,由于它必需要经过反射,在不晓得详细的派生范例中,完成对它们所含有成员变量的值的比力。因而,发起在ag真人完成一个值范例的数据布局时,同时重写ValueType.Equals()办法。
l 但是ag真人再转头看看援用范例,偶然两个援用范例的工具每每被用来举行相似值范例的比力,好比:String范例,它固然是援用范例,但它也重写了Equals办法,由于ag真人拿它来判别两个string能否相反(Equality),实践是盼望判别它们能否具有相反的内容,这是一个value semantics。因而,ag真人发起在思索完成一个用作值语义情况下的援用范例时分,也重写基类的Object.Equals()办法。
注:请参考MDSN或别的相干文档,怎样完成Equals办法的重写。
下面的图示给了很好的例子来区分Equals和ReferenceEquals办法,被用来做Equility和Identity判别的区别。
==运算符是可由类重载的运算符,它也是用来判别恒等的。 关于未重载==的援用范例,会比力两个援用范例能否援用统一个工具。这跟援用范例的Equals()办法是一样的。
关于未重载==的值范例,该运算符会比力这两个值能否"按位"相称,便是否这两个值中的每个字段都相称。和Equals办法一样,保举在自界说值范例中,也要重载==运算符,由于也存在反射在服从上的影响。
==运算符和Equals办法的区别在于多态体现上。Equals办法是重写,而==运算符是被重载。这意味着除非编译器晓得挪用详细的重载版本,不然它只是挪用未重载的==版本。
参考材料: 《Essential .NET, Volume 1: The Common Language》 By DonBox, Chris Sells 《Applied Microsoft .NET Framework Programming》By Jeffrey Richter
|