在C#中比较字符串和对象

时间:2014-01-22 08:59:11

标签: c# .net 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和Object时,我得到true 但是当我在第二个代码中比较它们时,我得到false

两个字符串都相同,但为什么当我追加到字符串时,我的结果会返回false

6 个答案:

答案 0 :(得分:90)

在每种情况下,==的第二个操作数为x,其类型为object。这意味着您正在使用普通的引用相等运算符。

现在,在第一种情况下,您使用两个具有相同内容的字符串常量。 C#编译器将为这两个引用使用单个对象。在第二种情况下,xy引用具有相同内容的不同字符串对象。这两个引用会有所不同,因此==将返回false。

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

  • 使用Equals代替 - string覆盖 (而不是只有重载的==运算符 >:

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

    如果任一参数可以为null,则使用静态Equals(object, object)方法会很有用;这意味着您无需担心NullReferenceException

  • 创建string类型的两个变量,此时==内的string重载将在编译时被选中,并且该重载会比较字符串的内容,而不仅仅是参考文献

值得注意的是,这不仅仅是C#编译器注意到字符串文字本身的问题 - 它是关于编译时常量表达式的。例如:

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

这里使用两个字符串文字来初始化y,其中不是与用于初始化x的字符串相同,但字符串连接由编译器执行,这意味着它与x已经使用的字符串相同。

答案 1 :(得分:30)

初始化时

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

它在内存中初始化它并分配对x的引用。在此之后初始化时

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

ref

编译器发现此值已经在内存中,因此它为y指定了相同的引用。

现在==等于运算符,它实际上比较了地址而不是值,找到两个变量的相同地址,结果为true:

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)

现在比较找到导致错误的不同地址:

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

所以要克服这一点,你需要使用.Equals()而不是引用来比较值和对象类型。

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

答案 2 :(得分:7)

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

答案 3 :(得分:6)

在后台,每次修改现有字符串时都会创建一个新字符串,因为字符串是不可变的,这意味着它们无法更改。

请参阅以下内容以获取解释:Why .NET String is immutable?

答案 4 :(得分:6)

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

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

如果双方的操作数都引用同一个对象,则

“==”运算符基本上返回true。在第一种情况下,x和y表示相同的对象,在秒的情况下,x和y表示相同的对象。 y引用不同的对象。

答案 5 :(得分:3)

你试过了吗?

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