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

看这个代码:

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

因此,当我比较字符串和对象在第一个代码,我得到 true
但是当我用第二代码比较它们时,我得到了 false

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

20252 次浏览

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

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

在每种情况下,==的第二个操作数是 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的字符串相同。

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

你有没有试过:

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

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

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

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

当你初始化

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

它在内存中初始化它,然后在初始化时指定对 x 的引用

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

ref

编译器发现该值已经在内存中,因此它将相同的引用分配给 y。

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

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 ()来代替 reference 来比较值和对象类型。

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