为什么此代码显示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);
}
}
我是否正确理解,在进行比较时,它们不是作为字符串而是作为对象进行比较的,这就是为什么不比较它们的值而是它们所指向的地址的原因?
答案 0 :(得分:3)
对于预定义的值类型,如果相等运算符(
==
)的操作数相等,则返回true
,否则返回false
。对于string
以外的引用类型,如果==
的两个操作数引用同一个对象,则返回true
。对于string
类型,==
比较字符串的值。
由于不能保证T
是通用的值类型,因此编译器必须假定它是引用类型。
答案 1 :(得分:2)
我通常会同意您的意见,但您的榜样特别好。
我是否正确理解,在进行比较时,它们不是作为字符串而是作为对象进行比较的,这就是为什么不比较它们的值而是它们所指向的地址的原因?
那实际上不是真的。
如==
文档所述,
对于字符串以外的引用类型,如果
==
的两个操作数引用相同的对象,则返回true。对于string
类型,==
比较字符串的值。
在您的特定情况下,原因是您在比较它们之前将它们转换为泛型。但是,如果这些是字符串对象,则将比较值。
答案 2 :(得分:1)
我发现创建一个非通用的OpTest
方法来确认正在发生的事情很有帮助。通用方法将参数视为Object
类型,而不对==
使用String
重载,这是比较值的一种特殊情况。
在两种情况下,参数的类型均为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);
}
}