在类"对象"中定义的==运算符在哪里?

喵喵喵*_*喵喵喵 40 .net c#

我搜索了FCL的源代码,我对此string.Equals()使用感到困惑Object.ReferenceEquals(),并Object.ReferenceEquals()使用==operator to jugde.然后我找不到如何==定义运算符.

那么原始运算符在哪里定义?

Chr*_*tos 27

这是该语言用于验证两个值是否相同的运算符.当你的代码被编译时,这个运算符将在CIL中被适当地编译,然后当我们将由CLR执行时,将比较两个值以检查它们是否相同.

例如,这是该Main方法的CIL代码:

在此输入图像描述

编译器为以下程序生成(它是一个控制台应用程序):

class Program
{
    static void Main(string[] args)
    {
        int a = 3;
        int b = 4;
        bool areEqual = a == b;
        Console.WriteLine(areEqual);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意IL_0007行.有一个ceq指令已经发出.这是您正在寻找的,==运营商.

重要的提示

==没有超载时会发生这种情况.


Dam*_*ver 17

当没有重载==运算符(如此处)时,编译器会发出ceq指令.在这一点上,没有更多的C#代码可供查看.

比较两个值.如果它们相等,则将整数值1(int32)推送到评估堆栈; 否则0(int32)被推到评估堆栈上.


Bil*_*eal 5

C# 中的重载operator==是调用静态函数的语法糖。与所有重载决议一样,重载决议是基于对象的静态类型而不是动态类型进行的。我们再看一下Object.ReferenceEquals

public static bool ReferenceEquals (Object objA, Object objB) {
    return objA == objB;
}
Run Code Online (Sandbox Code Playgroud)

objA这里,和的静态类型objBObject。动态类型可以是任何类型;字符串,其他一些用户定义的类型,等等;不要紧。调用哪个operator==函数是在编译此函数时静态确定的,因此您始终会获得默认的、非重载的、语言提供的内置函数。.NET 可能只是没有一个ReferenceEquals并让用户这样做((object)a) == ((object)b),但有一个特定的命名函数来说明正在发生的事情可以提高清晰度。

Object.Equals另一方面,它只是一个虚函数。因此,与任何其他虚拟函数调用一样,Equals选择哪个是基于 左侧对象的动态类型。.Equals(