繁体   English   中英

为什么C#!=运算符通过引用比较值类型?

[英]Why is the C# != operator comparing value types by reference?

我有以下代码返回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;
        }

这是令人惊讶的,因为只比较了一个类型的字段,并且每个字段的值都与即时窗口输出匹配:

?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"}

我在这里忽略了什么? 当比较值上的整数时,我使用!=和==“无处不在”。

当您这样做时:

(row1[fieldNames[i]] != row2[fieldNames[i]]) 

row[x]给您一个object请参阅http://msdn.microsoft.com/zh-cn/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");

调试输出:
等于=真

由于DataRow.Item索引器具有Object的返回类型,因此在返回任何值类型之前,都需要对它们进行装箱 随后,对包含您的值的对象实例(而不是值本身)执行相等比较。 要执行值比较,您需要通过将值强制转换回其正确类型来取消装箱,或使用多态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在上述情况下可以正常工作的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM