你的泛型方法基本被執行參考平等檢查 - 和s1
的價值觀和s2
指不同但平等的字符串。你可以這樣更容易證明這一點:
string x = "test";
string y = new string(x.ToCharArray());
Console.WriteLine(x == y); // Use string overload, checks for equality, result = true
Console.WriteLine(x.Equals(y)); // Use overridden Equals method, result = true
Console.WriteLine(ReferenceEquals(x, y)); // False because they're different objects
Console.WriteLine((object) x == (object) y); // Reference comparison again - result = false
請注意,您在OpTest
約束不改變其==
運營商使用。這是在編譯時根據T
的限制確定的。請注意,運營商絕不會覆蓋,只有超載。這意味着實現是在編譯時選擇的,而不管執行時的類型如何。
如果您約束T
以導致==
運算符過載的某種類型,那麼編譯器將使用該過載。例如:
using System;
class SillyClass
{
public static string operator ==(SillyClass x, SillyClass y) => "equal";
public static string operator !=(SillyClass x, SillyClass y) => "not equal";
}
class SillySubclass : SillyClass
{
public static string operator ==(SillySubclass x, SillySubclass y) => "sillier";
public static string operator !=(SillySubclass x, SillySubclass y) => "very silly";
}
class Test
{
static void Main()
{
var x = new SillySubclass();
var y = new SillySubclass();
OpTest(x, y);
}
static void OpTest<T>(T x, T y) where T : SillyClass
{
Console.WriteLine(x == y);
Console.WriteLine(x != y);
}
}
這裏OpTest
方法不使用重載運營商 - 但永遠只能從SillyClass
,不SillySubclass
的人。
它有助於查看IL例如使用ildasm自己研究這種行爲。 – Jeroen
如果您想在泛型代碼中使用「EqualityComparer .Default.Equals(s,t)」進行比較,並且可以選擇允許用戶通過他們自己的「IEqualityComparer 」。 –
CodesInChaos
[C#==和Equals()之間的區別可能重複](https://stackoverflow.com/questions/814878/c-sharp-difference-between-and-equals) – Dukeling