在Class" object"中定义的==运算符在哪里?

时间:2015-12-09 07:05:12

标签: c# .net

我搜索了FCL的源代码,我感到困惑的是string.Equals()使用Object.ReferenceEquals()Object.ReferenceEquals()使用==运算符来jugde。然后我无法找到如何定义==运算符。

原定的运营商定义在哪里?

4 个答案:

答案 0 :(得分:27)

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

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

Enter image description here

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

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

注意IL_0007行。已发出ceq条指令。这是您正在寻找的==运营商。

重要提示

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

答案 1 :(得分:17)

当没有重载的==运算符(如此处)时,编译器会发出ceq指令。此时不再需要查看C#代码。

  

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

答案 2 :(得分:4)

ceq从堆栈中获取两个值并给出结果。如果结果值为1则认为它们相等,如果它们不相等则为0。

但是,==运算符并不总是转换为ceq。 C#中的==ceq会导致are data types primitivesdo they have custom == operatorsare they references等。{/ p>

答案 3 :(得分:3)

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

public static bool ReferenceEquals (Object objA, Object objB) {
    return objA == objB;
}

此处,objAobjB的静态类型为Object。动态类型可以是任何东西;一个字符串,一些其他用户定义的类型,等等;那不重要。编译此函数时,确定调用哪个operator==是静态确定的,因此您始终可以获得默认的,非重载的,内置语言提供的函数。 .NET可能没有ReferenceEquals并且让用户执行((object)a) == ((object)b),但是具有特定的命名功能来说明正在进行的操作可以提高清晰度。

另一方面,

Object.Equals只是一个虚函数。因此,选择Equals基于.Equals(左侧对象的动态类型,就像任何其他虚函数调用一样。