2010-03-26 72 views
5

我有一个应用程序需要确定用户是否对对象进行了更改。所以,第一次加载对象时,我创建了一个深层副本(使用序列化/反序列化)并将副本保存到单独的字段。副本变为myCurrentObject,原始副本变为myOriginalObject测试对象的更改

现在我需要测试myCurrentObject的变化,我打算将它与myOriginalObject进行比较。我需要的是一个boolean结果,表明是否进行了任何更改。我已经确定一个简单的哈希码比较不起作用。即使没有变化,GetHashCode()也会为两个对象生成不同的结果。

我准备写一个方法来做一个属性的属性比较,但在我之前,我想我会检查是否有一个更简单和更可重用的方式来测试myCurrentObject以查看它是否已从myOriginalObject更改。

有什么建议吗?谢谢你的帮助。

回答

2

如果某个属性发生更改时发生事件会怎么样?

​​

5

相反,你可以实现对每个属性的OnPropertyChanged事件,那么你可以去看一看该事件被丢进。如果您专门实现INotifyPropertyChanged,您将获得可以做WPF绑定的附加好处,如果您想要的话。

如果这是不可能的,你可能可以实现一个反射解决方案,该解决方案将遍历这两个对象寻找差异。

+0

这肯定会做到这一点。从我+1。 – 2010-03-26 17:06:48

1

您可以添加一个脏标志,指示任何字段已更改。在属性集中设置脏标志。

public bool IsDirty { get { return m_IsDirty; } } 
public string Name { 
    set 
    { 
     m_Name = value; 
     m_IsDirty = true; 
    } 
} 
0

我通常做这些类型的测试是这样的:

public string sodomizar(myObject object) 
{ 
    return object.prop1.ToString() + object.prop2.ToString(); 
} 

然后进行测试:

if(sodomizar(object1)==sodomizar(object2)) 
{ 
doStuff(); 
} 
2
  1. 您可以重写GetHashCode方法,以满足您的需求。
  2. 哈希码只能告诉你一个对象已经明确地改变了,它不能告诉你一个对象肯定没有改变(因为不同的对象可以返回相同的哈希码)。
  3. 做调查Object.Equals方法
+0

有帮助 - 这是来自我的+1。 – 2010-03-26 17:07:20

0

我会考虑使用含有两个事物的抽象超:

  • ,声明“轨道 变化”是开启还是不是一个标志(默认为 假)
  • a包含键值历史记录的词典实例

...然后在您感兴趣的每个属性访问器中调用Base.TrackChange(string,object)更改。传递的字符串是属性的名称(使用反射/从堆栈跟踪中拉出属性名称: - 表示每个方法中的代码可以完全相同)...传递的对象只是元变量的值”。一些仔细的反射/堆栈跟踪检查可能意味着您可以删除此方法中的字符串参数...意味着您将实体Class 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; 
    } 
}