c#中字符串之间的比较

本文关键字:比较 之间 字符串 | 更新日期: 2024-04-23 16:05:22

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

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

将把a的值放在字符串池中,在搜索池时发现ba相同后,将为变量b分配相同的引用。好的,很清楚。但如果:

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

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

c#中字符串之间的比较

对象可以与其在堆中的引用进行比较。如果这是它们在本机中使用的方式,那么大多数对象将不便于比较,所以像string这样的东西实际上实现了相等运算符的重载,以更直观。string通过首先检查内存引用(通过首先调用object.ReferenceEquals(object, object))来比较相等(通过相等==运算符),如果不是相同的引用,则返回到比较字符串中的字符,而不考虑内存位置。

字符串文字(如"somethingNew")被编译为一个变量,该变量引用了.NET所称的内部内存池中的字符串值。。。这是一种方法,所有具有相同值(意思是大小写和字符相同)的字符串都充当指向实习生池中单个引用的指针,而不是每个字符串都为相同的值分配自己的内存。这节省了内存,但代价是在实习生池中查找值。这是因为字符串是不可变的(只读),所以通过与++=运算符串联或以其他方式更改字符串的值实际上会创建一个全新的字符串。默认情况下,字符串变量不是内部变量,除非它们是文字。

示例中的字符串比较将在初始字符串相等对象引用检查中成功,并返回true,而无需对相等进行任何进一步分析。之所以会发生这种情况,是因为您的变量是字符串文字,因此是内部的(具有相同的内存地址)。如果他们没有被拘留,那么无论记忆位置如何,比较都会回到性格比较。

您可以使用string.Intern(string) 手动插入非文字字符串

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

不正确;==运算符可能过载,并且事实上对于string过载的。

但如果:

使用字符串比较;然而,即使它们不是:因为数据来自文字(ldstr),在这种情况下,由于"interning",相同的字符串实例将导致,所以即使使用引用比较,它仍然可以工作。

这仍然是完全相同的情况,字符串文字不必有变量名。请记住,字符串重写运算符==(),这样您就可以对字符串内容进行比较,而不仅仅是简单的对象比较。所以这也同样有效:

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

嗯,这让我很困惑,因为我得到的关于这个主题的信息是以一种愚蠢的方式构建的,首先解释说引用类型之间的比较是通过使用运算符"=="的地址来完成的(所有这些都发布在bold中,解释大约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相同对象的引用吗?