The main difference between the two is polymorphism. Operators are overloaded, not overridden, which means that unless the compiler knows to call the more specific version, it'll just call the identity version. To illustrate that, here's an example: using System;public class Test{ static void Main() { // Create two equal but distinct strings string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); Console.WriteLine (a==b); Console.WriteLine (a.Equals(b)); // Now let's see what happens with the same tests but // with variables of type object object c = a; object d = b; Console.WriteLine (c==d); Console.WriteLine (c.Equals(d)); }}The results are: TrueTrueFalseTrueThe third line is False because the compiler can only call the non-overloaded version of == as it doesn't know that the contents of c and d are both string references. As they are references to different strings, the identity operator returns false.
using System;public class Test{ static void Main() { // Create two equal but distinct strings string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); Console.WriteLine (a==b); Console.WriteLine (a.Equals(b)); // Now let's see what happens with the same tests but // with variables of type object object c = a; object d = b; Console.WriteLine (c==d); Console.WriteLine (c.Equals(d)); }}
TrueTrueFalseTrue
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.