C#相等判断实例报错分析及解决

栏目: ASP.NET · 发布时间: 5年前

内容简介:线上报来一个问题,说用户的数据丢失了。开发经过紧张的调查。终于找到了原因。if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex)){

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

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 , 上面的结果又会有所不同,有兴趣的同学可以自己尝试一下。

是否可以这样理解,我们在int32 装箱后的对象上调用Equals 方法,会走到Int32的Equals 方法上?因为看object 方法的Equals 并没有看到这个逻辑。

-----------------------------------------------------------------------

object.cs

[__DynamicallyInvokable]

public virtual bool Equals(object obj)

{

return RuntimeHelpers.Equals(this, obj);

}

[__DynamicallyInvokable]

public static bool Equals(object objA, object objB)

{

if (objA == objB)

return true;

if (objA == null || objB == null)

return false;

return objA.Equals(objB);

}

-------------------------------------------------------------------

RuntimeHelper.cs

[SecuritySafeCritical]

[MethodImpl(MethodImplOptions.InternalCall)]

public new static extern bool Equals(object o1, object o2);

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2019-01/1565.64htm


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高性能MySQL

高性能MySQL

施瓦茨 (Baron Schwartz)、扎伊采夫 (Peter Zaitsev)、特卡琴科 (Vadim Tkachenko) / 宁海元、周振兴、彭立勋、翟卫祥,刘辉 / 电子工业出版社 / 2013-5-1 / 128.00元

《高性能mysql(第3版)》是mysql 领域的经典之作,拥有广泛的影响力。第3 版更新了大量的内容,不但涵盖了最新mysql 5.5版本的新特性,也讲述了关于固态盘、高可扩展性设计和云计算环境下的数据库相关的新内容,原有的基准测试和性能优化部分也做了大量的扩展和补充。全书共分为16 章和6 个附录,内容涵盖mysql 架构和历史,基准测试和性能剖析,数据库软硬件性能优化,复制、备份和恢复,高可......一起来看看 《高性能MySQL》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具