比较C#中的string和对象

看到这个代码:

object x = "mehdi emrani"; string y = "mehdi emrani"; Console.WriteLine(y == x); 

返回true

但是这个代码:

 object x = "mehdi emrani"; string y = "mehdi "; y += "emrani"; Console.WriteLine(y == x); 

返回false

所以当我比较第一个代码中的string和对象时,我变为true
但是当我在第二个代码中比较它们时,我得到了false

这两个string是相同的,但为什么当我追加到string,我的结果返回false

在每种情况下, ==的第二个操作数是x ,它是objecttypes的。 这意味着你正在使用正常的参考相等运算符。

现在在你的第一个例子中,你使用了两个具有相同内容的string常量 。 C#编译器将为这两个引用使用单个对象。 在第二种情况下, xy引用具有相同内容的不同string对象。 这两个引用将是不同的,所以==将返回false。

您可以通过以下方式修复比较:

  • 使用Equals来代替 – string 覆盖 (相对于只有重载==运算符)

     Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x) 

    如果两个参数中的任何一个都可以为null,那么使用静态Equals(object, object)方法会很有用。 这意味着你不需要担心NullReferenceException

  • 创build两个stringtypes的variables,此时string==重载将在编译时被选中,并且重载比较string的内容,而不仅仅是引用

值得注意的是,这不仅仅是C#编译器注意到的string本身的问题,而是关于编译时常量expression式的问题。 举个例子:

 object x = "mehdi emrani"; string y = "mehdi " + "emrani"; Console.WriteLine(y == x); // True 

这里y是使用两个不同于初始化x的string来初始化的,但是string连接是由编译器执行的,它意识到它是已经用于xstring。

当你初始化

 object x = "mehdi emrani"; //pointer(x) 

它在内存中初始化它并为x分配引用。 之后当你初始化

 string y = "mehdi emrani"; //pointer(x) 

REF

编译器发现这个值已经在内存中,所以它给y赋值相同的引用。

现在==相等的运算符,实际上比较地址而不是值find两个variables相同的地址结果是:

 x==y //actually compares pointer(x)==pointer(x) which is true 

在第二种情况下,当你初始化x和y分配不同的地址。

 object x = "mehdi emrani"; //Pointer(x) string y = "mehdi "; //not found in memory y += "emrani"; //Pointer(y) 

现在比较查找结果为false的不同地址:

 x == y //is actually Pointer(x) == Pointer(y) which is false 

所以为了克服这个问题,你需要使用.Equals()而不是引用来比较值和对象的types。

 Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true 

最有可能的是比较引用(标准Equals对象实现)。 在第一个例子中,C#优化了常量string,所以y和x实际上指向同一个对象,因此它们的引用是相等的。 在另一种情况下,y是dynamic创build的,所以引用是不同的。

在后台,每次修改现有的string都会创build一个新的string,因为string是不可变的,这意味着它们不能改变。

请参阅以下说明: 为什么.NETstring是不可变的?

在第一种情况下,.NET会执行string常量优化,并只分配一个String实例。 x和y都指向相同的对象(两个引用都是相等的)。

但在第二种情况下,x和y指向不同的String实例。 将“ermani”添加到y将创build第三个string对象。

如果两边的操作数引用同一个对象,则“==”操作符基本上返回true。 在第一种情况下,x和y表示同一个对象,在秒情况下,x和y表示不同的对象。

你有没有尝试过:

 Console.WriteLine(y == x.ToString());