==如何工作以及它在.NET内部做什么

时间:2014-08-09 09:49:48

标签: .net equality

这是我的示例代码。

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的机器上执行的

2 个答案:

答案 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对该值的引用