了解代码的一些背景知识。我有一个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;
}
答案 0 :(得分:2)
这里的问题是OldValue
和NewValue
在编译时是object
,而不是int
,因此==
/ {{1}运算符调用!=
类定义的运算符,因为all operators are static
。 object
运算符检查引用是否相等,而不是逻辑相等,因此只检查两个参数是否完全相同(C ++中的指针相同)
要解决这个问题,你有几个选择
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))