0

昨天当我在这里发布一个问题的答案时,我遇到了问题,在不同的情况下如何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}

并在这里这里阅读文章

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

4

2 回答 2

2

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

C# == 操作员文档

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

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

总结一下:

  1. com1: result = (obj == str2);// true
    • 比较objectstring执行引用相等检查
    • obj 和 str2 指向同一个引用,所以结果为真
  2. 结果 = (obj == str3);// 假
    • 比较objectstring执行引用相等检查
    • obj 和 str3 指向不同的引用,因此结果为 false
  3. 结果 = (obj == str4);// 真
    • 比较objectstring执行引用相等检查
    • obj 和 str4 指向同一个引用,所以结果为真
  4. 结果 = (str2 == str3);// 真
    • 比较stringstring执行字符串值检查
    • str2 和 str3 都是“字符串”,所以结果为真
  5. 结果 = (str2 == str4);// 真
    • 比较stringstring执行字符串值检查
    • str2 和 str4 都是“字符串”,所以结果为真
  6. 结果 = (str3 == str4);// 真
    • 比较stringstring执行字符串值检查
    • str3 和 str4 都是“字符串”,所以结果为真
  7. result = (obj == obj2);// false - 比较objectobject执行引用相等检查 - obj 和 obj2 指向不同的引用,因此结果为 false

请记住,==执行的比较类型是在编译时选择的,因此它基于操作数的静态类型。编译器不知道 obj 和 obj2 将始终指向字符串。

于 2013-02-27T06:08:09.297 回答
0

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

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

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

最后,相等运算符检查Strings 值之间的相等性。如果是

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

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

于 2013-02-27T05:38:32.060 回答