[英]Comparison of Generics in C#
Why does this code prints False? 为什么这段代码打印错误?
class Program
{
public static void OpTest<T>(T s, T t) where T : class
{
Console.WriteLine(s == t);
}
static void Main()
{
string s1 = "string";
System.Text.StringBuilder sb = new System.Text.StringBuilder(s1);
string s2 = sb.ToString();
OpTest(s1, s2);
}
}
Do I understand correctly that when compared, they are compared not as strings, but as objects, which is why not their values are compared, but the addresses to which they point? 我是否正确理解,比较时,它们不是作为字符串进行比较,而是作为对象进行比较,这就是为什么不比较它们的值,而是它们指向的地址?
From the docs for the ==
operator : 从==
运算符的文档 :
For predefined value types, the equality operator (
==
) returnstrue
if the values of its operands are equal,false
otherwise. 对于预定义的值类型,如果操作数的值相等,则相等运算符(==
)返回true
,否则返回false
。 For reference types other thanstring
,==
returnstrue
if its two operands refer to the same object. 对于除string
之外的引用类型,如果其两个操作数引用同一对象,则==
返回true
。 For thestring
type,==
compares the values of the strings. 对于string
类型,==
比较string
的值。
Since T
cannot be guaranteed to be a value type as it's generic, the compiler must assume it is a reference type. 由于T
不能保证是值类型,因为它是通用的,因此编译器必须假定它是引用类型。
I would normally go and agree with you in the comments, but your example is especially good. 我通常会在评论中同意你,但你的例子特别好。
Do I understand correctly that when compared, they are compared not as strings, but as objects, which is why not their values are compared, but the addresses to which they point? 我是否正确理解,比较时,它们不是作为字符串进行比较,而是作为对象进行比较,这就是为什么不比较它们的值,而是它们指向的地址?
That is actually not true. 实际上并非如此。
As stated in the ==
documentation, 如==
文档中所述,
For reference types other than string,
==
returns true if its two operands refer to the same object. 对于除string之外的引用类型,如果其两个操作数引用同一对象,则==
返回true。 For thestring
type,==
compares the values of the strings. 对于string
类型,==
比较string
的值。
In your particular case, the reason is you're casting them as generics before comparing them. 在您的特定情况下,原因是您在比较它们之前将它们作为泛型。 But if those were string objects, the value would be compared. 但如果这些是字符串对象,则会比较该值 。
I find it helpful to create a non-generic OpTest
method to confirm what's happening. 我发现创建一个非通用的OpTest
方法来确认发生了什么是有帮助的。 The generic method treats the parameters as Object
types and does not use the ==
overload for String
, which is a special case to compare the values. 泛型方法将参数视为Object
类型,并且不对String
使用==
重载,这是比较值的特殊情况。
In both cases the parameters are type String
but the generic method treats them "generically" when making the comparison. 在这两种情况下,参数都是String
类型,但泛型方法在进行比较时会“一般”处理它们。
void Main()
{
string s1 = "string";
System.Text.StringBuilder sb = new System.Text.StringBuilder(s1);
string s2 = sb.ToString();
TestClass.OpTest(s1, s2);
TestClass.OpTest<string>(s1, s2);
// OpTest: s is System.String, t is System.String
// True
// OpTest<T>: s is System.String, t is System.String
// False
}
public class TestClass
{
public static void OpTest(string s, string t)
{
Console.WriteLine($"OpTest: s is {s.GetType()}, t is {t.GetType()}");
// Uses String's == operator, which compares the values
Console.WriteLine(s == t);
}
public static void OpTest<T>(T s, T t) where T : class
{
Console.WriteLine($"OpTest<T>: s is {s.GetType()}, t is {t.GetType()}");
// Uses Object's == operator, which is a reference comparison
Console.WriteLine(s == t);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.