字符串比较 :为什么我们对以下情况有不同的输出
本文关键字:情况 输出 比较 为什么 我们 字符串 | 更新日期: 2023-09-27 17:56:47
为什么我们对以下情况有不同的输出:
object obj = "Int32";
string str1 = "Int32";
string str2 = typeof(int).Name;
Console.WriteLine(obj == str1); // true
Console.WriteLine(str1 == str2); // true
Console.WriteLine(obj == str2); // false !?
答案很简单:
将object
与string
进行比较时,将使用引用比较,仅当两个对象具有相同的引用时,才会为真。
比较字符串时,将使用字符串比较,如果字符串内容相同,无论它们是否是相同的引用,则为真。
在第三次比较中,您使用的是object
比较,其中比较两个内容相同但引用不同的字符串,因此它将返回 false。
增加的复杂性是前两个字符串具有相同的引用,因为它们是编译时常量,并且已由编译器interned
,以便它们引用内存中的同一字符串。
我用这个解释注释了你的原始代码:
object obj = "Int32"; // As a compile-time constant string, this will be interned.
string str1 = "Int32"; // This is also interned, so has the same reference as obj
string str2 = typeof(int).Name; // Same contents as str1, but a different reference
// (created at runtime, so it wasn't interned)
Console.WriteLine(obj == str1); // Reference comparison: true because the references are the same
Console.WriteLine(str1 == str2); // String comparison: true because the string contents are the same.
Console.WriteLine(obj == str2); // Reference comparison: false because the references different.
也:
- 如果您使用的是Resharper,它实际上会警告您进行第一次和最后一次比较,并说:"可能无意的参考比较"。
您可以通过声明 str2 获得相同的结果,如下所示:
字符串 str2 = 字符串。Concat("Int", "32");
obj == str2
行使用引用比较。而obj == str1
线则没有。
为什么?
.NET 中的string
类型是隐式引用类型。但这不是同一时间。它是技术上是引用类型的类型之一,但它已被编程为充当值类型,并且是不可变的,这意味着它不会被直接修改。
当您创建一个新string
时,会为其分配一个引用,该引用是您的string
变量所包含的。你可以用这个string
做各种各样的事情,但你永远无法改变它。如果重新分配该值,则只会创建一个新引用。
在本例中,obj == str1
行使用引用比较,但引用实际上匹配。由于它们都是硬编码的,因此编译器和 .NET 可以对它们使用相同的引用。(正如我们之前所说,字符串是不可变的。您应该阅读Matthew发布的interning
链接以获取更多信息。
那么,如果字符串匹配,为什么 .NET 要创建不同的引用?
考虑可以在内存中创建的大量对象。如果在任何时候创建了一个新string
并且 .NET 遍历了所有其他字符串以找到匹配的字符串,则程序将非常慢。你几乎无法完成任何真正的工作。
因此,.NET 对此进行了优化。如果你稍微改变一下代码,你就会明白我的意思。
object obj = "Int32";
string str1 = typeof(int).Name;
string str2 = typeof(int).Name;
Console.WriteLine(obj == str1); // false
Console.WriteLine(str1 == str2); // true
Console.WriteLine(obj == str2); // false !?
str1 == str2
行仍然返回 true,因为它实际上是在比较字符串,而obj == str1
行现在是 false,因为它也在比较这些字符串的引用。