String.Equals和==的行为

时间:2013-02-27 05:23:53

标签: c#

昨天当我发布问题here的答案时,我遇到问题String.Equals==在不同情况下的行为有何不同。

我希望得出String.Equals==行为的结论。

bool result = false;

    object obj = "String"; 
    string str2 = "String";
    string str3 = typeof(string).Name;
    string str4 = "String";
    object obj2 = str3; 

    // obj, str2, str4 references are same.
    // obj is object type and others are string type

    // Comparision between object obj and string str2 -- Com 1
    result = String.Equals(obj, str2);// true
    result = String.ReferenceEquals(obj, str2); // true
    result = (obj == str2);// true

    // Comparision between object obj and string str3 -- Com 2
    result = String.Equals(obj, str3);// true
    result = String.ReferenceEquals(obj, str3); // false
    result = (obj == str3);// false

    // Comparision between object obj and string str4 -- Com 3
    result = String.Equals(obj, str4);// true
    result = String.ReferenceEquals(obj, str4); // true
    result = (obj == str4);// true

    // Comparision between string str2 and string str3 -- Com 4
    result = String.Equals(str2, str3);// true
    result = String.ReferenceEquals(str2, str3); // false
    result = (str2 == str3);// true

    // Comparision between string str2 and string str4 -- Com 5
    result = String.Equals(str2, str4);// true
    result = String.ReferenceEquals(str2, str4); // true
    result = (str2 == str4);// true

    // Comparision between string str3 and string str4 -- Com 6
    result = String.Equals(str3, str4);// true
    result = String.ReferenceEquals(str3, str4); // false
    result = (str3 == str4);// true

    // Comparision between object obj and object obj2 -- Com 7
    result = String.Equals(obj, obj2);// true
    result = String.ReferenceEquals(obj, obj2); // false
    result = (obj == obj2);// false

我也看着手表

obj     "String" {1#}   object {string}
str2    "String" {1#}   string
str3    "String" {6#}   string
str4    "String" {1#}   string
obj2    "String" {6#}   object {string}

并阅读文章herehere

为什么Com1,Com2,Com3,Com4,Com5和Com6有不同的行为?

2 个答案:

答案 0 :(得分:2)

==运算符对strings和所有其他引用类型具有不同的行为。如果==的两个操作数均为string,则使用String.Equals比较。否则==相当于Object.ReferenceEquals

来自C# == Operator documentation

  

对于预定义的值类型,等于运算符(==)返回true,如果   其操作数的值相等,否则为false。以供参考   除了string之外的类型,==如果它的两个操作数引用则返回true   同一个对象。对于字符串类型,==比较的值   字符串。

您看到的另一个效果是string intering。您的代码中只有一个对文字"String"值的引用。您的代码相当于:obj = str2 = str4 = "String"。 obj,str2和str4都是对相同底层字符串的引用。由于str3是在运行时生成的,因此它被设置为具有相同值“String”的不同字符串。

总结:

  1. com1:result =(obj == str2); // true
    • 比较objectstring,因此执行参考等式检查
    • obj和str2指向相同的引用,因此结果为真
  2. result =(obj == str3); // false
    • 比较objectstring,因此执行参考等式检查
    • obj和str3指向不同的引用,因此结果为false
  3. result =(obj == str4); // true
    • 比较objectstring,因此执行参考等式检查
    • obj和str4指向相同的引用,因此结果为真
  4. result =(str2 == str3); // true
    • 比较stringstring,因此执行字符串值检查
    • str2和str3都是“String”,因此结果为真
  5. result =(str2 == str4); // true
    • 比较stringstring,因此执行字符串值检查
    • str2和str4都是“String”,因此结果为真
  6. result =(str3 == str4); // true
    • 比较stringstring,因此执行字符串值检查
    • str3和str4都是“String”,因此结果为真
  7. result =(obj == obj2); // false - 比较objectobject,以便执行引用相等性检查 - obj和obj2指向不同的引用,因此结果为false
  8. 请记住==执行的比较类型是在编译时选择的,因此它基于操作数的静态类型。编译器不知道obj和obj2总是指向字符串。

答案 1 :(得分:0)

Equals比较引用类型的引用和值类型的值。 String是一种行为类似于值类型的引用类型。 String可以存储大量数据,这就是它应该存储在堆上的原因,但它是不可变的,并且行为与任何其他值类型一样。

Equals上的String方法将字符串的值与另一个对象(必须是String)进行比较。

ReferenceEquals确定两个引用类型是否是同一个实例。由于String是引用类型,但是它们是不可变的,它们被实现以允许不同的字符串引用相同的字符串文字。

最后,等于运算符检查String s的值之间的相等性。在

的情况下

typeof(string).Name == (object)"String"

结果将返回false,因为左操作数实际上是嵌入在字符串类型定义中的常量,并且不共享对字符串文字的相同引用,并且因为右操作数被加框,所以它们的引用被比较。 / p>