C#相等判断实例报错分析及处理
发布时间:2021-12-05 13:16:45 所属栏目:教程 来源:互联网
导读:线上报来一个问题,说用户的数据丢失了。开发经过紧张的调查。终于找到了原因。 if (newData.GetValue(rowIndex) == oldData.GetValue(rowIndex)) { .................. } public object GetValue(string fieldName)) { ............... return values[filed
线上报来一个问题,说用户的数据丢失了。开发经过紧张的调查。终于找到了原因。 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); ![]() (编辑:宿州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐