2010-03-26 68 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; 
    } 
}