线上报来一个问题, 说用户的数据丢失了. 开发经过紧张的调查. 终于找到了原因.
- if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex))
- {
- ..................
- }
- public object GetValue(string fieldName))
- {
- ...............
- return values[filedName]; // 这是一个简单类型: int,string
- }
问题出在了 if 中的比较上. values[rowIndex] 中保存的是一个整数, 开发认为两个整数比较实用 == 就可以了.
但是 values[rowIndex] 中的整数经过 GetValue 返回后被作为 object 对象返回了, 这时如果还使用 == 进行比较就会出现不等的情况.
我们来看一个更全面的例子:
- static void Main(string[] args)
- {
- object value1 = new object();
- object value2 = new object();
- value1 = 2;
- value2 = 2;
- Console.WriteLine("value1 == value2 {0}", (value1 == value2).ToString());
- Console.WriteLine("vvalue1.Equals(value2) {0}", value1.Equals(value2).ToString());
- Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
- Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());
- }
运行结果
- value1 == value2 False
- value1.Equals(value2) True
- Equals(value1, value2) True
- ReferenceEquals(value1,value2) False
如果我们将 value1, value2 都定义为数字, 但是一个是 long, 一个是 uint.
- static void Main(string[] args)
- {
- long value1 = 2;
- int value2 = 2;
- Console.WriteLine("value1 == value2 {0}", (value1 == value2).ToString());
- Console.WriteLine("value1.Equals(value2) {0}", value1.Equals(value2).ToString());
- Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
- Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());
- }
看一下运行结果 , 使用 == , 和 value1.Equals 方法比较是相等的.
- value1 == value2 True
- value1.Equals(value2) True
- Equals(value1, value2) False
- ReferenceEquals(value1,value2) False
结合上面两个例子, 我们定义一个 long 变量, 一个 unit 变量, 给它们赋值之后, 再将这两个变量赋值给两个 object 对象.
- static void Main(string[] args)
- {
- object value1 = new object();
- object value2 = new object();
- long lgval = 2;
- int ival = 2;
- value1 = lgval;
- value2 = ival;
- Console.WriteLine("lgval == ival {0}", (lgval == ival).ToString());
- Console.WriteLine("value1 == value2 {0}", (value1 == value2).ToString());
- Console.WriteLine("value1.Equals(value2) {0}", value1.Equals(value2).ToString());
- Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
- Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());
- }
可以看到, 除去值类型 lgval 和 uval 相等外, 其它都是不相等的.
- lgval == uval True
- value1 == value2 False
- value1.Equals(value2) False
- Equals(value1, value2) False
- ReferenceEquals(value1,value2) False
是不是很抓狂? 到底什么情况下相等? 什么情况下不等? 我们先将上面的结果总结一下.
value1 和 value2 都是 Object 对象 含有相同类型的值对象(int) 含有相同的值 | value1 是 long,value2 是 int 含有相同的值 | value1 和 value2 都是 Object 对象 含有不同类型的值对象 (long,int) 含有相同的值 | |
value1 == value2 | false | true | false |
value1.Equals(value2) | true | true | false |
Equals(value1, value2) | true | false | false |
ReferenceEquals(value1,value2) | false | false | false |
如果将一个值类型赋值给一个 object 对象后, 如何判断相等? 微软官方也没有给出一个标准的说法. 从测试的角度来看.
两个比较的 object 中的内容如果类型相同, 可以使用 Equals 来进行比较.
不过我个人还是建议如果是比较值, 还是转换为对应的值类型进行比较, 这样比较清晰, 不容易犯错, 大家也不用搞清楚 == 和 Equals 之前的细微差别.
ps: 如果 object 的类型是 string , 上面的结果又会有所不同, 有兴趣的同学可以自己尝试一下.
来源: https://www.cnblogs.com/xixiuling/p/10155822.html