经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
一次线上问题引发的对于C#中相等判断的思考
来源:cnblogs  作者:西秀岭  时间:2018/12/24 10:43:17  对本文有异议

线上报来一个问题,说用户的数据丢失了。开发经过紧张的调查。终于找到了原因。

  1. if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex))
  2. {
  3. ..................
  4. }
  5. public object GetValue(string fieldName))
  6. {
  7. ...............
    return values[filedName]; //这是一个简单类型: int,string
  8. }

 问题出在了 if 中的比较上。  values[rowIndex] 中保存的是一个整数,开发认为两个整数比较实用 ==  就可以了。

但是 values[rowIndex] 中的整数经过 GetValue返回后被作为 object 对象返回了,这时如果还使用 == 进行比较就会出现不等的情况。

 

我们来看一个更全面的例子:

  1. static void Main(string[] args)
  2. {
  3. object value1 = new object();
  4. object value2 = new object();
  5. value1 = 2;
  6. value2 = 2;
  7. Console.WriteLine("value1 == value2 {0}", (value1 == value2).ToString());
  8. Console.WriteLine("vvalue1.Equals(value2) {0}", value1.Equals(value2).ToString());
  9. Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
  10. Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());
  11. }

运行结果

value1  == value2 False
value1.Equals(value2) True
Equals(value1, value2) True
ReferenceEquals(value1,value2) False

 

如果我们将value1, value2 都定义为数字,但是一个是long,一个是uint.

  1. static void Main(string[] args)
  2. {
  3.    long value1 = 2;
  4. int value2 = 2;
  5. Console.WriteLine("value1 == value2 {0}", (value1 == value2).ToString());
  6. Console.WriteLine("value1.Equals(value2) {0}", value1.Equals(value2).ToString());
  7. Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
  8. Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());
  9. }

看一下运行结果 ,使用  ==  ,和 value1.Equals  方法比较是相等的。

  1. value1 == value2 True
  2. value1.Equals(value2) True
  3. Equals(value1, value2) False
  4. ReferenceEquals(value1,value2) False

 

结合上面两个例子,我们定义一个long 变量, 一个unit 变量, 给它们赋值之后,再将这两个变量赋值给两个object 对象。

  1. static void Main(string[] args)
  2. {
  3. object value1 = new object();
  4. object value2 = new object();
  5. long lgval = 2;
  6. int ival = 2;
  7. value1 = lgval;
  8. value2 = ival;
  9. Console.WriteLine("lgval == ival {0}", (lgval == ival).ToString());
  10. Console.WriteLine("value1 == value2 {0}", (value1 == value2).ToString());
  11. Console.WriteLine("value1.Equals(value2) {0}", value1.Equals(value2).ToString());
  12. Console.WriteLine("Equals(value1, value2) {0}", Equals(value1, value2).ToString());
  13. Console.WriteLine("ReferenceEquals(value1,value2) {0}", ReferenceEquals(value1,value2).ToString());
  14. }

可以看到,除去值类型 lgval 和 uval 相等外,其它都是不相等的。

  1. lgval == uval True
  2. value1 == value2 False
  3. value1.Equals(value2) False
  4. Equals(value1, value2) False
  5. ReferenceEquals(value1,value2) False

 是不是很抓狂? 到底什么情况下相等?什么情况下不等?我们先将上面的结果总结一下。

 
 

value1 和value2都是Object 对象

含有相同类型的值对象(int)

含有相同的值

value1 是long,value2 是 int

含有相同的值

value1 和value2都是Object 对象

含有不同类型的值对象(long,int)

含有相同的值

  1. value1 == value2
false  true   false
  1. value1.Equals(value2)
true  true   false
  1. Equals(value1, value2)
 true false   false
  1. ReferenceEquals(value1,value2)
 false false   false

 

 

 

 

 

 

 

 

 

 

 

 

如果将一个值类型赋值给一个object 对象后,如何判断相等? 微软官方也没有给出一个标准的说法。从测试的角度来看。

两个比较的 object 中的内容如果类型相同,可以使用Equals 来进行比较。

不过我个人还是建议如果是比较值,还是转换为对应的值类型进行比较,这样比较清晰,不容易犯错,大家也不用搞清楚 == 和 Equals 之前的细微差别。

 

ps: 如果object 的类型是 string , 上面的结果又会有所不同,有兴趣的同学可以自己尝试一下。

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号