为什么存储在对象变量中并与 == 比较的字符串有这种奇怪的行为? [英] Why strings stored in object variables and compared with == have this strange behavior?

查看:25
本文介绍了为什么存储在对象变量中并与 == 比较的字符串有这种奇怪的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用反射比较两个字符串属性时的奇怪行为.

var a = new A{X = "aa",乙 = 1};var b = 新 A{X = "aa",乙 = 2};类型类型 = typeof(A);object aObjValue = type.GetProperty("X")?.GetValue(a);object bObjValue = type.GetProperty("X")?.GetValue(b);Console.WriteLine("aObjValue == bObjValue :" + (aObjValue == bObjValue));Console.WriteLine("aObjValue.Equals(bObjValue):" + aObjValue.Equals(bObjValue));a.X = Console.ReadLine();aObjValue = type.GetProperty("X")?.GetValue(a);Console.WriteLine("aObjValue == bObjValue :" + (aObjValue == bObjValue));Console.WriteLine("aObjValue.Equals(bObjValue):" + aObjValue.Equals(bObjValue));a.X = "aa";aObjValue = type.GetProperty("X")?.GetValue(a);Console.WriteLine("aObjValue == bObjValue :" + (aObjValue == bObjValue));Console.WriteLine("aObjValue.Equals(bObjValue):" + aObjValue.Equals(bObjValue));Console.ReadKey();//aObjValue == bObjValue : 真//aObjValue.Equals(bObjValue) : 真//aa//aObjValue == bObjValue : False//aObjValue.Equals(bObjValue) : 真//aObjValue == bObjValue : 真//aObjValue.Equals(bObjValue) : 真

当使用 Console.ReadLine() 并手动将 a.X 分配给aa"时,我得到 false 但再次在代码中分配时,我得到 true.这对我来说是意想不到的行为.有人可以解释一下这里发生了什么吗?

解决方案

所以你知道 该字符串重载了相等运算符 == 以使用 Equals.但是由于您将它们存储在 Object 变量中,因此它们使用的是 Object 中的版本,该版本仅比较引用.

同样,字符串是一种特殊类型,它使用一种叫做 字符串实习 以提高性能.因此,如果您使用字符串文字 "aa",如果已经存在字符串文字 "aa",则不会分配新内存.这是这里的情况.这就是为什么第一个 aObjValue == bObjValue 返回 true,两者是相同的引用.

在第二种情况下,您将字符串 "aa" 输入到控制台.这不会使用字符串实习(这是一个编译器特性),所以它是一个全新的 String 实例.这就是为什么第二个 aObjValue == bObjValue 返回 false 的原因.如果您将它们转换为 String,您可以使用 == 并且您将获得预期的行为(与 String.Equals 相同).

Strange behavior when comparing two string properties with the usage of reflection.

var a = new A
{
    X = "aa",
    B = 1
};

var b = new A
{
    X = "aa",
    B = 2
};

Type type = typeof(A);

object aObjValue = type.GetProperty("X")?.GetValue(a);
object bObjValue = type.GetProperty("X")?.GetValue(b);

Console.WriteLine("aObjValue == bObjValue : " + (aObjValue == bObjValue));
Console.WriteLine("aObjValue.Equals(bObjValue) : " + aObjValue.Equals(bObjValue));

a.X = Console.ReadLine();

aObjValue = type.GetProperty("X")?.GetValue(a);

Console.WriteLine("aObjValue == bObjValue : " + (aObjValue == bObjValue));
Console.WriteLine("aObjValue.Equals(bObjValue) : " + aObjValue.Equals(bObjValue));

a.X = "aa";

aObjValue = type.GetProperty("X")?.GetValue(a);

Console.WriteLine("aObjValue == bObjValue : " + (aObjValue == bObjValue));
Console.WriteLine("aObjValue.Equals(bObjValue) : " + aObjValue.Equals(bObjValue));

Console.ReadKey();

//aObjValue == bObjValue : True
//aObjValue.Equals(bObjValue) : True
//aa
//aObjValue == bObjValue : False
//aObjValue.Equals(bObjValue) : True
//aObjValue == bObjValue : True
//aObjValue.Equals(bObjValue) : True

When using Console.ReadLine() and manually assigning a.X to "aa" I'm getting false but when assigning it in code again I get true. This is unexpected behavior for me. Can someone explain me what is going on here?

解决方案

So you know that string overloads the equality operator == to use Equals. But since you store them in a Object variable they are using the version from Object which just compares references.

Again string is a special type, it uses something that is called string interning to improve performance. So if you use a string literal "aa" this will not allocate new memory if there was already a string literal "aa". This is the case here. That is why the first aObjValue == bObjValue returns true, both are the same reference.

In the second case you enter the string "aa" to the console. This will not use string interning(which is a compiler feature), so it is a brand new instance of String. That is why the second aObjValue == bObjValue returns false. If you would cast them to String you could use == and you would get the expected behavior(same as String.Equals).

这篇关于为什么存储在对象变量中并与 == 比较的字符串有这种奇怪的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆