42

I searched the source code of FCL, and I got confused that string.Equals() uses Object.ReferenceEquals(), and Object.ReferenceEquals() uses == operator to jugde. And then I can't find how the == operator is defined.

So where is the original operator defined?

2
  • 5
    Im pretty sure its part of the C# language itself and not part of objects. Commented Dec 9, 2015 at 7:11
  • 1
    it's feature derived from C# language. By default, the operator == tests for reference equality by determining if two references indicate the same object, so reference types do not need to implement operator == in order to gain this functionality. - from msdn Commented Dec 9, 2015 at 7:16

4 Answers 4

26

This is an operator that the language uses to validate that two values are the same. When your code would be compiled this operator would be compiled appropriately in CIL and then when we will be executed by the CLR the two values would be compared to be checked if they are the same.

For instance, this is the CIL code for the Main method:

Enter image description here

that the compiler produces for the following program (it's a console application):

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

Note the IL_0007 line. There a ceq instruction has been emitted. This is that you are looking for, the == operator.

Important Note

This is happening when the == is not overloaded.

Sign up to request clarification or add additional context in comments.

Comments

18

When there isn't an overloaded == operator (as here), the compiler emits a ceq instruction. There's no more C# code to look at at this point.

Compares two values. If they are equal, the integer value 1 (int32) is pushed onto the evaluation stack; otherwise 0 (int32) is pushed onto the evaluation stack.

Comments

5

Overloading operator== in C# is syntactic sugar for calling a static function. The overload resolution, like all overload resolution, happens based on the static type of the object, not the dynamic type. Let's look at Object.ReferenceEquals again:

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

Here, the static type of objA and objB is Object. The dynamic type can be anything; a string, some other user defined type, whatever; that does not matter. The determination of which operator== is called is determined statically when this function is compiled, so you always get the default, non-overloaded, built in language-supplied one. .NET could just have not had a ReferenceEquals and let users do ((object)a) == ((object)b), but having a specific named function to say what's going on improves clarity.

Object.Equals, on the other hand, is just a virtual function. As a result, which Equals is chosen is based on the dynamic type of the object to the left of the .Equals(, like any other virtual function call.

Comments

4

ceq takes two values from the stack and gives results. If the result value is 1 then they are considered equal and 0 if they are not equal.

However, the == operator doesn't always get translated to ceq. Whether == in C# results in ceq depends on some more factors like are data types primitives or do they have custom == operators or are they references.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.