字符串的行为.等于和==
本文关键字:字符串 | 更新日期: 2023-09-27 18:01:31
昨天当我在这里张贴一个问题的答案时,我遇到了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为什么有不同的行为?
==
操作符对于strings
和所有其他引用类型具有不同的行为。如果==
的两个操作数都是string
,则使用String.Equals
比较。否则==
等于Object.ReferenceEquals
来自c# == Operator文档:
对于预定义的值类型,相等操作符(==)返回true其操作数的值相等,否则为false。供参考非string类型,如果其两个操作数引用,==返回true同样的物体。类型的值进行比较字符串。
您看到的另一个效果是字符串交互。在您的代码中只有一个对文字"String"
值的引用。您的代码相当于:obj = str2 = str4 = "String"
。Obj、str2和str4都是对同一个底层字符串的引用。由于str3是在运行时生成的,因此它被设置为具有相同值" string "的不同字符串。
总结:
- com1: result = (obj == str2);//true
- 比较
object
和string
,因此执行引用相等性检查 - obj和str2指向相同的引用,所以结果为true
- 比较
- result = (obj == str3);//false
- 比较
object
和string
,因此执行引用相等性检查 - obj和str3指向不同的引用,所以结果是false
- 比较
- result = (obj == str4);//true
- 比较
object
和string
,因此执行引用相等性检查 - obj和str4指向相同的引用,所以结果为true
- 比较
- result = (str2 == str3);//true
- 比较
string
和string
,因此执行字符串值检查 - str2和str3都是"String"所以结果为真
- 比较
- result = (str2 == str4);//true
- 比较
string
和string
,因此执行字符串值检查 - str2和str4都是"String"所以结果是true
- 比较
- result = (str3 == str4);//true
- 比较
string
和string
,因此执行字符串值检查 - str3和str4都是"String"所以结果是true
- 比较
- result = (obj == obj2);//false-比较
object
和object
,执行引用相等性检查- obj和obj2指向不同的引用,所以结果是false
请记住,==
执行的比较类型是在编译时选择的,因此它基于操作数的静态类型。编译器不知道obj和obj2总是指向字符串。
Equals
比较引用类型的引用和值类型的值。String
是一个引用类型,其行为类似于值类型。String
可以存储大量数据,这就是为什么它应该存储在堆上,但它是不可变的,并且像任何其他值类型一样。
String
上的Equals
方法将字符串的值与另一个对象(必须是String
)的值进行比较。
ReferenceEquals
判断两个引用类型是否为同一实例。由于String
s是引用类型,但不可变,因此它们被internned以允许相同的字符串字面值被不同的字符串引用。
最后,相等运算符检查String
s的值是否相等。对于
typeof(string).Name == (object)"String"
结果将返回false
,因为左操作数实际上是嵌入在字符串类型定义中的常量,不共享对字符串文字的相同引用,并且由于右操作数被装箱,它们的引用被比较。