我有一个应用程序需要确定用户是否对对象进行了更改。因此,当首次加载对象时,我创建一个深层副本(使用序列化/反序列化)并将副本保存到单独的字段中。副本变为myCurrentObject
,原始变为myOriginalObject
。
现在我需要对myCurrentObject
进行更改测试,我计划将其与myOriginalObject
进行比较。我只需要boolean
结果,表明是否进行了任何更改。我已经确定一个简单的哈希码比较不起作用。 GetHashCode()
会为两个对象生成不同的结果,即使没有更改也是如此。
我正准备编写一个方法来进行逐个属性的比较,但在此之前,我想我会检查是否有更简单,更可重用的方法来测试myCurrentObject
看看它是否已从myOriginalObject
更改。
有什么建议吗?谢谢你的帮助。
答案 0 :(得分:5)
相反,您可以在每个属性上实现OnPropertyChanged事件,然后您就可以看到是否抛出了该事件。如果您专门实现了INotifyPropertyChanged,那么您将获得额外的好处,即如果您愿意,可以执行WPF绑定。
如果无法做到这一点,您可能会实现一个带有反射的解决方案,该解决方案将遍历两个寻找差异的对象。
答案 1 :(得分:2)
如果在更改属性时引发事件会怎样?
答案 2 :(得分:2)
答案 3 :(得分:1)
您可以添加一个脏标志,指示任何字段已更改。在属性集中设置脏标志。
public bool IsDirty { get { return m_IsDirty; } }
public string Name {
set
{
m_Name = value;
m_IsDirty = true;
}
}
答案 4 :(得分:0)
我通常会做这样的测试:
public string sodomizar(myObject object)
{
return object.prop1.ToString() + object.prop2.ToString();
}
然后测试:
if(sodomizar(object1)==sodomizar(object2))
{
doStuff();
}
答案 5 :(得分:0)
我会考虑使用包含两件事的抽象超类:
...然后在您感兴趣的每个属性访问器中调用Base.TrackChange(string,object)。传递的字符串是Property的名称(使用反射/从堆栈跟踪中拉出属性名称: - 表示每个方法中的代码可以完全相同)...并且传递的对象只是元变量'value ”。一些仔细的反射/堆栈跟踪检查可能意味着您可以删除此方法上的字符串参数...意味着您将实体C#编码要求保持在最低限度。
该标志位于那里,因为对象的基本状态初始化意味着可以进行属性更改(设置访问器调用),直到对象第一次完全水合。
字典是否可以跟踪更改(审计?)等等。如果您在'IsDirty'问题上所需要的只是简单的真/假,则将其缩放回第二个布尔值。
类似的东西:
public abstract Class EntityBase
{
private bool _changesAreTracking = false;
private Dictionary<string, object> _changes = null;
public EntityBase() {}
public TrackChange(string propertyName, object value)
{
if(_changesAreTracking)
{
if(_changes == null) { _changes = new Dictionary<string, object>(); }
_changes.Add(propertyName, value);
}
}
public void StartTrackChanges()
{
_changesAreTracking = true;
}
public bool HasChanged()
{
bool returnThis = false;
if(_changes != null && _changes.Keys.Count() > 0)
{
returnThis = true;
}
return returnThis;
}
public bool HasChanged(string propertyName)
{
bool returnThis = false;
if(_changes != null && _changes.Keys.Contains(propertyName))
{
returnThis = true;
}
return returnThis;
}
}