Нет разницы между этими двумя. Вы путаете переопределение Equals
(которое не вызывается ни в одной из реализаций) с перегрузкой ==
(что не будет иметь значения в любом фрагменте, поскольку перегрузка выполняется в время компиляции, и компилятор не знает достаточно о T
, чтобы использовать какую-либо конкретную перегрузку).
Просто чтобы показать, что я имею в виду:
static void ThrowIfFoo<T>(this T argument, string name) where T : class
{
if (argument == "foo")
{
throw new Exception("You passed in foo!");
}
}
Тестирование с:
"foo".ThrowIfFoo(); // Throws
string x = "f";
x += "oo"; // Ensure it's actually a different reference
x.ThrowIfFoo(); // Doesn't throw
ThrowIfFoo
не знает, что T
будет строкой - потому что это зависит от вызывающего кода - и разрешение перегрузки выполняется только , когда ThrowIfFoo
компилируется . Поэтому он использует оператор ==(object, object)
вместо ==(string, string)
.
Другими словами, это так:
object foo1 = "foo";
string tmp = "f";
object foo2 = tmp + "oo";
Console.WriteLine(foo1.Equals(foo2)); // Prints True
Console.WriteLine(foo1 == foo2); // Prints false
Console.WriteLine((string) foo1 == (string) foo2); // Prints True
В последней строке компилятор знает, что может использовать перегрузку ==, поскольку оба операнда имеют типов времени компиляции типов string
.