C#相等判断实例报错分析及解决
线上报来一个问题,说用户的数据丢失了。开发经过紧张的调查。终于找到了原因。
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);
- C#使用回溯法解决背包问题实例分析
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断
- C#使用动态规划解决0-1背包问题实例分析
- C#中??和?分别是什么意思? 在ASP.NET开发中一些单词的标准缩写 C#SESSION丢失问题的解决办法 在C#中INTERFACE与ABSTRACT CLASS的区别 SQL命令语句小技巧 JQUERY判断CHECKBOX是否选中三种方法 JS中!=、==、!==、===的用法和区别 在对象比较中,对象相等和对象一致分别指的是什么?
- Hadoop分析日志实例的详细步骤及出现的问题分析和解决
- C#中数组段用法实例分析
- C#装箱和拆箱操作实例分析
- KingDZ 变菜鸟,每日一个C#小实例之---C#判断网络是否链接
- .NET深入学习笔记(2):C#中判断空字符串的4种方法性能比较与分析
- C#编程实现对象与JSON串互相转换实例分析
- C#中参数个数可变的方法实例分析
- seajs模块压缩问题与解决方法实例分析
- c# js前端判断实例
- C#中事务处理和非事务处理方法实例分析
- .NET学习笔记-2:C#中判断空字符串的4种方法性能比较与分析
- C# WINFORM判断程序是否运行,且只能运行一个实例
- 第二人生的源码分析(七十六)判断程序运行多个实例
- C#判断是否相等
- C# 通过分析netstat -an所得信息 查看本机所监听的端口 及判断某端口是否可用
- C#中IEnumerable接口用法实例分析