2013-03-27 25 views
1

這不是一個如何做某事的問題,而是我如何更好地實現某些內容或以不同方式思考問題。使用撤銷修改集合中的類

我有一個winforms應用程序,允許用戶選擇網格中的多行。這些行代表帳戶,當用戶選擇帳戶並點擊按鈕時,對象的布爾屬性將更改爲所選值,而不管其現有狀態如何。但是,如果驗證方法失敗,則會向用戶發送消息,並且布爾屬性需要設置回原始狀態。

public void ModifyAccounts(List<DemoAccount> accts, bool updateIsSpecial) 
{ 
    // Dictionary that will hold the account ID along with the booleans original state 
    Dictionary<int, bool> originalState = new Dictionary<int, bool>(); 
    foreach(var acct in accts) 
    { 
     // Add the current state to the dictionary 
     originalState.Add(acct.Id, acct.IsSpecial); 

     acct.IsSpecial = updateIsSpecial; 
    } 

    // Send the list to another method that loops through each account and checks 
    // for specific validation rules. Returns a collection of tuples. The tuple 
    // contains the account for item1 and a bool validated flag for item2 
    var valAccounts = ValidateAccounts(accts); 

    var failedAccounts = from obj in valAccounts 
         where !acct.Item2 
         select new 
            { 
             account = obj.Item1, 
             isValid = obj.Item2 
            }; 

    if (failedAccounts.Count() > 0) 
    { 
     // Alert the user with custom msg box method that the accounts failed 
     // Do Custom Method 

     // Reset the values of the failed accounts to their previous state. 
     // It is possible that some accounts passed validation and were saved, 
     // only the failed accounts should be reset. 
     foreach (var obj in failedAccounts) 
     { 
      bool originalFlagState = false; 
      originalFlagStates.TryGetValue(obj.account.Id, out originalFlagState); 
      var origAccount = accts.Where(x => x.Id == obj.account.Id).FirstOrDefault(); 
      origAccount.IsSpecial = originalFlagState; 

     } 
    } 
} 

我希望這不是太混亂。我只有3年的開發經驗,這不是很多。但是,我覺得在處理某些事情時足夠了解,如果感覺有更好的方法,那麼我可能沒有正確或有效地做到這一點。修改帳戶標誌會更改帳戶列表中的對象。很明顯,將對象添加到新列表只會創建對該對象的引用。所以我不能做像舉行2集合一個修改和其他原始狀態的東西。我也不能做深層複製,因爲帳戶類沒有標記爲可序列化。由於對象的類型,我無法改變它。

感謝任何能提供一些建議或見解的人!

+1

你可以驗證之前,你改變狀態?任何未通過驗證的內容都將保持不變。 – 2013-03-27 12:53:25

+0

驗證通過更改獲取我的賬戶列表以查看更改是否可接受。可以對帳戶進行多項更改,以便此方法循環訪問帳戶並檢查所有屬性,並在出現問題時引發無效標誌。因此,修改帳戶時,初始未更改的數據基本上已經過驗證。當我將列表發送給驗證方法時,我必須將標誌設置爲用戶更改的內容,現在可以設置包含該類的任何其他集合。 – Tom 2013-03-27 13:33:48

+0

我會親自找到預先驗證數據的方法。你讓不好的數據進入,這很糟糕(即使你只保留一段時間)。如果你有多個線程,你很容易就會遇到數據損壞問題,並且在維護代碼時,你將有更大的可能性破壞某些東西。 – 2013-03-27 14:03:18

回答

1

我不明白你爲什麼要更改後,而不是事先驗證。 但是,如果您確實需要驗證並在之後使用撤消,則有支持此行爲的設計模式

查看命令模式。下面是介紹如何實現它 http://www.codeproject.com/Articles/8303/Using-the-Command-pattern-for-undo-functionality

在您的特定情況下,我將通過命令堆棧迭代,並撤銷其在失敗中使用的所有命令佔

它可能看起來像這樣

代碼項目鏈接
foreach (var obj in failedAccounts) 
     foreach ICommand command in commandStack 
       If(command.element.Equals(obj)) 
        command.undo; 

command.element應該包含你想用你的命令改變的元素。

如果你不想要兩個foreach你可以使用System.Linq操作