I searched the source code of FCL, and I got confused that string.Equals() uses Object.ReferenceEquals(), and Object.ReferenceEquals() use
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.