在“对象”类中定义==运算符在哪里?

我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; } 

这里, objAobjB的静态types是Object 。 dynamictypes可以是任何东西; 一个string,一些其他用户定义types,无论如何; 不要紧。 当调用这个函数时,决定调用哪个operator==是静态的,所以你总是得到默认的,非重载的,用语言提供的。 .NET可能只是没有一个ReferenceEquals ,让用户做((object)a) == ((object)b) ,但有一个特定的命名函数来说明发生了什么提高了清晰度。

另一方面, Object.Equals只是一个虚函数。 因此,select哪个Equals是基于.Equals(左边的对象的dynamictypes.Equals(就像任何其他的虚拟函数调用一样。