比较两个相等的变量返回false

时间:2014-12-08 20:53:02

标签: c# asp.net-mvc-4 reflection

了解代码的一些背景知识。我有一个MVC应用程序,我的所有模型都实现了IModel。 IModel只强制拥有int Id属性。

以下方法"更新"视图模型中可用数据的模型实例。对于viewmodel的每个属性,它检查模型中是否存在相应的属性,如果是,它会使用viewmodel的值更新模型中的值(如果值不同)。

最后一点出错了。声明:OldValue!= NewValue总是返回true,即使f.e.两者都是整数,1。为什么?

public static Boolean UpdateIfChanged<M, VM>(this M Model, VM ViewModel) where M : IModel
{
    Boolean HasUpdates = false;
    Type Mtype = typeof(M);
    PropertyInfo[] MProperties = Mtype.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    Type VMtype = typeof(VM);
    PropertyInfo[] VMProperties = VMtype.GetProperties(BindingFlags.Public | BindingFlags.Instance);

    foreach (var VMProperty in VMProperties)
    {
        if (!VMProperty.PropertyType.GetInterfaces().Any(x => x.Name == typeof(IModel).Name) 
            && MProperties.Any(x => x.Name == VMProperty.Name) 
            && Mtype.GetProperty(VMProperty.Name).PropertyType ==  VMProperty.PropertyType )
        {
            var OldValue = Mtype.GetProperty(VMProperty.Name).GetValue(Model);
            var NewValue = VMtype.GetProperty(VMProperty.Name).GetValue(ViewModel);
            if (NewValue != null)
            {
                if (OldValue == null)
                {
                    Mtype.GetProperty(VMProperty.Name).SetValue(Model, NewValue);
                    HasUpdates = true;
                }
                else
                {
                    if (OldValue != NewValue)
                    {
                        Mtype.GetProperty(VMProperty.Name).SetValue(Model, NewValue);
                        HasUpdates = true;
                    }
                }
            }
        }
    }
    return HasUpdates;
}

4 个答案:

答案 0 :(得分:2)

这里的问题是OldValueNewValue在编译时是object,而不是int,因此== / {{1}运算符调用!=类定义的运算符,因为all operators are staticobject运算符检查引用是否相等,而不是逻辑相等,因此只检查两个参数是否完全相同(C ++中的指针相同)

要解决这个问题,你有几个选择

  • 正如Tigran所提到的,输入显示的值,因此您最终使用object中定义的运算符而不是int
  • 调用object.Equals(OldValue, NewValue),它检查null然后调用object Object.Equals(object o),这将调用在调用对象的实际类/结构中定义的函数(在这种情况下) virtual

答案 1 :(得分:1)

您的GetValue(..)调用返回盒装整数 对象,因此引用类型。

因此你的代码:

 //OldValue and NewValue are Object types and NOT integers !
 if (OldValue != NewValue)

比较引用而不是

当您使用{隐藏'具体类型的var关键字时,您没有注意到这一点。

要正确克服此问题,可以这样做:

 ....
 var OldValue = (int)Mtype.GetProperty(VMProperty.Name).GetValue(Model); //cast to int
 var NewValue = (int)VMtype.GetProperty(VMProperty.Name).GetValue(ViewModel);//cast to int
 ....

答案 2 :(得分:0)

试试这个if (OldValue.ToString() != NewValue.ToString())。或者,如果OldValue / NewValue是int-s:if ((int)OldValue != (int)NewValue)

答案 3 :(得分:0)

更好的语法是:

if (!Equals(OldValue, NewValue))