这不是一个关于如何做某事的问题,而是我如何更好地实现某些事情或以不同的方式思考问题。
我有一个winforms应用程序,允许用户在网格中选择多行。这些行表示帐户,当用户选择帐户并点击按钮时,对象上的布尔属性将更改为所选值的任何值,而不管其现有状态如何。但是,如果验证方法失败,则会向用户发送一条消息,并且需要将boolean属性设置回其原始状态。
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年的开发经验,这不是很多。但是,我觉得在理解某些事情的时候就足够了解如果感觉有更好的方式,那么我可能没有正确或有效地做到这一点。修改帐户标志会更改帐户列表中的对象。显然,将对象添加到新列表只会创建对该对象的引用。所以我不能做一些事情,比如拿一个集合进行修改,另一个进行原始状态。我也无法进行深层复制,因为帐户类未标记为可序列化。由于对象的类型,我无法改变这一点。
感谢任何能提供一些建议或见解的人!
答案 0 :(得分: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操作