这是我的示例代码。
string a = "test";
object c = a;
Console.WriteLine(a == c);
Console.WriteLine(object.Equals(a, c));
Console.WriteLine(a.Equals(c));
Console.WriteLine(c.Equals(a));
在这种情况下,输出如下
True
True
True
True
这是另一个代码示例
string a = "test";
string b = "te";
object c = b + "st";
Console.WriteLine(a == c);
Console.WriteLine(object.Equals(a, c));
Console.WriteLine(a.Equals(c));
Console.WriteLine(c.Equals(a));
现在这个案例更有趣,因为输出就是这个
False
True
True
True
这真的让我觉得我问自己这个问题,==
如何比较两个对象?我寻找答案,但我找不到任何可以解释这个的东西?谁能解释一下呢。这是在使用.NET 4.5.1的机器上执行的
答案 0 :(得分:4)
对于参考类型,默认情况下,==
是参考比较器。正如Jon Skeet在他的评论中指出的那样,string
会覆盖此行为,因此它可以提供值匹配语义。也就是说,您尝试的方案将在两个变量都为string
类型的情况下工作。 c
被输入为object
这一事实意味着==
的重载并未被使用。
尽管您可能会考虑实习,但字符串是不同的引用,因为字符串实习仅在编译时默认情况下发生。在运行时,只有在手动调用string.Intern
并且c
仅在运行时已知(编译器无法对其进行优化)时才会实现字符串。因此,此代码段手动使用字符串实习,并使代码按照您希望的方式运行:
string a = "test";
string b = "te";
object c = string.Intern(b + "st");
// c == a is true
(最后一行查找字符串的实习版本,并返回该实例而不是创建新实例。)
同样,如果编译器不能保证字符串的值(因为字符串是变量,而不是字面值或常量),它就不会被实现。这一次,我将非常轻微地调整您的示例,以演示如何使c
的值成为编译时常量:
string a = "test"; // a literal, "test" - always fixed at compile time
const string b = "te"; // a constant - always fixed at compile time
object c = b + "st"; // a constant plus a literal - always fixed at compile time
// c == a is true
值得注意的是,当您在原始代码中比较a == c
时会出现编译器警告:"可能的意外参考比较;要进行价值比较,请在右侧输入' string'。'。"警告值得注意! ; - )
答案 1 :(得分:0)
Console.WriteLine(object.Equals(a, c));
Console.WriteLine(a.Equals(c));
Console.WriteLine(c.Equals(a));
以相同的方式工作,因为他们正在比较对象的价值,而
Console.WriteLine(a == c);
比较a和c对该值的引用