我有以下代码返回false:
private static bool AreRowsEqual(string[] fieldNames, DataRow row1, DataRow row2)
{
for (var i = 0; i <= fieldNames.Length - 1; i++)
{
if (row1[fieldNames[i]] != row2[fieldNames[i]])
{
return false;
}
}
return true;
}
这是令人惊讶的,因为只有一个long类型的字段被比较,并且每个字段的值根据即时窗口输出匹配:
?row1[fieldNames[i]];
34
?row2[fieldNames[i]];
34
?row1[fieldNames[i]].GetType();
{Name = "Int64" FullName = "System.Int64"}
[System.RuntimeType]: {Name = "Int64" FullName = "System.Int64"}
? row2[fieldNames[i]].GetType();
{Name = "Int64" FullName = "System.Int64"}
[System.RuntimeType]: {Name = "Int64" FullName = "System.Int64"}
我在这里忽略了什么?在比较整数值时,我使用!=和==“无处不在”。
答案 0 :(得分:6)
当你这样做时:
(row1[fieldNames[i]] != row2[fieldNames[i]])
row[x]
为您object
提供了http://msdn.microsoft.com/en-us/library/146h6tk5.aspx
如果您将对象与==
进行比较,则比较参考。
您必须转换为原始数据类型或与obj.Equals(obj2)
例如:
object a = 2;
object b = 2;
if (a == b)
Debug.WriteLine("== = true");
if (a.Equals(b))
Debug.WriteLine("equals = true");
调试输出:
equals = true
答案 1 :(得分:4)
由于DataRow.Item
索引器的返回类型为Object
,因此任何值类型在返回之前都需要boxed。随后,对包装值的对象实例执行相等比较,而不是对值本身执行。要执行值比较,您需要通过将值转换回正确的类型来取消装箱,或使用多态Equals
方法。
int i1 = 34;
int i2 = 34;
Console.WriteLine(i1 == i2); // gives true
object o1 = i1;
object o2 = i2;
Console.WriteLine(o1 == o2); // gives false
Console.WriteLine((int)o1 == (int)o2); // gives true
Console.WriteLine(o1.Equals(o2)); // gives true
编辑:您需要区分对象的运行时类型及其声明的类型。装箱时,您的商品的声明类型为object
(根据DataRow.Item
索引器的返回类型),但运行时类型仍为long
(或Int64
) 。诸如!=
之类的运算符将根据声明的类型进行解析,而在派生类中重写的实例方法将针对运行时类型进行调用。这就是Equals
在上述情况下正常工作的原因。