Оператор равенства универсальных типов C#

от https://msdn.microsoft.com/en-us/library/d5x73970.aspx

при применении ограничения where T: class избегайте == and != операторы по параметру type, поскольку эти операторы будут тестироваться для только ссылочная идентичность, а не равенство значений. Это даже так. если эти операторы перегружены в типе, который используется как аргумент. Следующий код иллюстрирует этот момент; выходные данные false, даже если класс String перегружает оператор==.

public static void OpTest<T>(T s, T t) where T : class
{
    System.Console.WriteLine(s == t);
}

static void Main()
{
    string s1 = "target";
    System.Text.StringBuilder sb = new System.Text.StringBuilder("target");
    string s2 = sb.ToString();
    OpTest<string>(s1, s2);
}

все в порядке, пока я не попытался следовать, с тем же методом

static void Main()
{
    string s1 = "target";
    string s2 = "target";
    OpTest<string>(s1, s2);
}

Он выводит "True", S1 и S2 ссылаются на разные объекты в памяти, даже если они имеют одинаковое значение? Я что-то упускаю?

1 ответов


строки интернированы в .NET, поэтому, когда вы делаете

string s1 = "target";
string s2 = "target";

Они оба указывают на один объект. Вот почему пример MSDN использует StringBuilder, это обманывает CLR в создании другого строкового объекта с тем же значением, так что тест оператора в общем методе вернет false.