c#中字符串的比较

时间:2013-11-24 21:28:45

标签: c# string string-comparison

因此,正如我们所知,对象(在当前示例中 - 字符串)相对于它们在堆中的引用进行比较。所以,如果:

string a = "something"; 
string b = "something"; 
bool isEqual = (a == b);

a 的值放入字符串池中,并在搜索完 b 的值后与 a 相同池,将为变量 b 分配相同的引用。好的,那很清楚。但是如果发生了什么:

string a = "somethingNew";
bool isEqual = (a == "somethingNew");

如何在内存中表示这样的比较文字(如果有的话)以及在这种情况下如何完成整个比较过程?

4 个答案:

答案 0 :(得分:12)

对象可以相对于它们在堆中的引用进行比较。如果这是它们原生使用的方式,大多数对象都不会比较人类友好,因此像string这样的事实上实现了相等运算符的重载更直观。 string通过首先检查内存引用(首先调用==)并且如果不是相同的引用来比较相等(通过相等object.ReferenceEquals(object, object)运算符),然后回退到比较字符串中的字符,无论记忆位置如何。

字符串文字(例如"somethingNew")被编译为一个变量,在.NET调用实习内存池时引用该字符串值...这是一种具有相同值的所有字符串的含义(意思相同) case和characters)都作为指向实习池中单个引用的指针,而不是每个引用都有相同值的内存分配。这样可以节省内存,但需要在实习池中查找值。这是因为字符串是不可变的(只读),因此通过与++=运算符串联来更改字符串的值,否则实际上会创建一个全新的字符串。默认情况下,字符串变量不会被中断,除非它们是文字。

示例中字符串的比较将在初始字符串相等对象引用检查上成功,并返回true而不进行任何进一步的相等性分析。这将发生,因为您的变量是字符串文字,因此实习(具有相同的内存地址)。如果没有实习,那么无论内存位置如何,比较都会回到字符比较中。

您可以使用string.Intern(string)

手动实习非文字字符串

答案 1 :(得分:5)

  

因此,正如我们所知,对象(在当前示例中 - 字符串)相对于它们在堆中的引用进行比较。

不正确的; ==运算符可能会超载,<{1}}的确实重载。

  

但是如果发生了什么:

使用字符串比较;但是,即使它们不是:因为该数据来自文字(string),因此“interning”会导致相同的字符串实例 - 所以即使它使用参考比较,它仍然可以工作。

答案 2 :(得分:1)

这仍然是完全相同的情况,您不必具有字符串文字的变量名称。请记住,字符串会覆盖operator ==(),因此您可以对字符串 content 进行比较,而不仅仅是普通对象比较。所以这也适用:

 string tail = "New";
 bool isEqual = (a == "something" + tail);

答案 3 :(得分:0)

呃,这让我非常困惑,因为我对这个主题的信息是以这种愚蠢的方式构建的,首先解释参考类型之间的比较是通过他们的地址完成的。 operator'=='(所有这些都以粗体发布,解释约4页长)。最重要的是,所有示例都是由字符串给出的,但是没有一个单词关于它们之间的任何值相等。所以,在这里发帖之后,我决定完成关于案例的整章和3页后(实际上最后一页上的最后一句)声明'=='有不同的行为当用它来比较字符串时。绝对愚蠢。 所以,只是为了最后检查,确保我有正确的信息:

用于字符串的

'=='首先检查两个变量是否引用同一个对象。如果没有,则在内容本身进行实际值比较。

使用字符串常量作为:bool isEqual = (a == "somethingNew");进行比较实际上会获得常量值,在所谓的池中搜索它,如果它有匹配,它会引用同一个对象吗?那么,它实际上将它分配为变量?对不起,这对我来说还有点不清楚。

最后一个(来自给定文章的一个例子):

string firstString = "deer";
string secondString = firstString;
string thirdString = "de" + 'e' + 'r';
cw(firstString == secondString); // True - same object
cw(firstString == thirdString); // True - equal objects
cw((object)firstString == (object)secondString); // True
cw((object)firstString == (object)thirdString); //False

在这种情况下,不应该在池中搜索thirdString的值,而整个变量是否要接收与firstString和secondString相同的对象的引用?