比较C#中的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和对象时,我变为true
。
但是当我在第二个代码中比较它们时,我得到了false
。
这两个string是相同的,但为什么当我追加到string,我的结果返回false
?
在每种情况下, ==
的第二个操作数是x
,它是object
types的。 这意味着你正在使用正常的参考相等运算符。
现在在你的第一个例子中,你使用了两个具有相同内容的string常量 。 C#编译器将为这两个引用使用单个对象。 在第二种情况下, x
和y
引用具有相同内容的不同string对象。 这两个引用将是不同的,所以==
将返回false。
您可以通过以下方式修复比较:
-
使用
Equals
来代替 – 被string
覆盖 (相对于只有重载的==
运算符)Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x)
如果两个参数中的任何一个都可以为null,那么使用静态
Equals(object, object)
方法会很有用。 这意味着你不需要担心NullReferenceException
。 -
创build两个
string
types的variables,此时string
的==
重载将在编译时被选中,并且重载比较string的内容,而不仅仅是引用
值得注意的是,这不仅仅是C#编译器注意到的string本身的问题,而是关于编译时常量expression式的问题。 举个例子:
object x = "mehdi emrani"; string y = "mehdi " + "emrani"; Console.WriteLine(y == x); // True
这里y
是使用两个不同于初始化x
的string来初始化的,但是string连接是由编译器执行的,它意识到它是已经用于x
string。
当你初始化
object x = "mehdi emrani"; //pointer(x)
它在内存中初始化它并为x分配引用。 之后当你初始化
string y = "mehdi emrani"; //pointer(x)
编译器发现这个值已经在内存中,所以它给y赋值相同的引用。
现在==
相等的运算符,实际上比较地址而不是值find两个variables相同的地址结果是:
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)
现在比较查找结果为false的不同地址:
x == y //is actually Pointer(x) == Pointer(y) which is false
所以为了克服这个问题,你需要使用.Equals()而不是引用来比较值和对象的types。
Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true
最有可能的是比较引用(标准Equals
对象实现)。 在第一个例子中,C#优化了常量string,所以y和x实际上指向同一个对象,因此它们的引用是相等的。 在另一种情况下,y是dynamic创build的,所以引用是不同的。
在后台,每次修改现有的string都会创build一个新的string,因为string是不可变的,这意味着它们不能改变。
请参阅以下说明: 为什么.NETstring是不可变的?
在第一种情况下,.NET会执行string常量优化,并只分配一个String实例。 x和y都指向相同的对象(两个引用都是相等的)。
但在第二种情况下,x和y指向不同的String实例。 将“ermani”添加到y将创build第三个string对象。
如果两边的操作数引用同一个对象,则“==”操作符基本上返回true。 在第一种情况下,x和y表示同一个对象,在秒情况下,x和y表示不同的对象。
你有没有尝试过:
Console.WriteLine(y == x.ToString());