在“对象”类中定义==运算符在哪里?
我search了FCL的源代码,并且我感到困惑, string.Equals()
使用Object.ReferenceEquals()
和Object.ReferenceEquals()
使用==
运算符来jugde。 然后我找不到如何定义==
运算符。
那么原来的运营商在哪里定义?
这是语言用来validation两个值是相同的运算符。 当你的代码被编译时,这个运算符会在CIL中被适当地编译,然后当我们被CLR执行时,这两个值将被比较,如果它们是相同的,那么将被检查。
例如,这是Main
方法的CIL代码:
编译器为以下程序生成(它是一个控制台应用程序):
class Program { static void Main(string[] args) { int a = 3; int b = 4; bool areEqual = a == b; Console.WriteLine(areEqual); } }
请注意IL_0007行。 有一个ceq
指令已经发出。 这是你正在寻找, ==
运算符。
重要的提示
==
没有超载时发生这种情况。
当没有重载的==
操作符时(如这里),编译器发出一个ceq
指令。 目前没有更多的C#代码可以看。
比较两个值。 如果相等,则将整数值1(int32)推入评估栈; 否则将0(int32)压入评估堆栈。
ceq
从栈中取两个值并给出结果。 如果结果值是1,那么它们被认为是相等的,如果它们不相等则为0。
但是, ==
运算符并不总是被转换为ceq
。 在C#中的==
是否导致ceq
取决于更多的因素,如are data types primitives
还是do they have custom == operators
或是are they references
。
在C#中重载operator==
是调用静态函数的语法糖。 像所有重载parsing一样,重载parsing基于对象的静态types而不是dynamictypes。 我们再来看一下Object.ReferenceEquals
:
public static bool ReferenceEquals (Object objA, Object objB) { return objA == objB; }
这里, objA
和objB
的静态types是Object
。 dynamictypes可以是任何东西; 一个string,一些其他用户定义types,无论如何; 不要紧。 当调用这个函数时,决定调用哪个operator==
是静态的,所以你总是得到默认的,非重载的,用语言提供的。 .NET可能只是没有一个ReferenceEquals
,让用户做((object)a) == ((object)b)
,但有一个特定的命名函数来说明发生了什么提高了清晰度。
另一方面, Object.Equals
只是一个虚函数。 因此,select哪个Equals
是基于.Equals(
左边的对象的dynamictypes.Equals(
就像任何其他的虚拟函数调用一样。