1

これは、何かを行う方法の問題ではなく、より良いものを実装したり、問題を別の方法で考えたりするにはどうすればよいかという問題です。

ユーザーがグリッド内の複数の行を選択できるようにする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 年ほどの開発経験しかありませんが、それほど多くはありません。しかし、より良い方法があると感じた場合、おそらくそれを正しくまたは効率的に行っていないことを理解するだけで十分だと思います。アカウント フラグを変更すると、アカウント リスト内のオブジェクトが変更されます。明らかに、オブジェクトを新しいリストに追加すると、そのオブジェクトへの参照が作成されます。そのため、修正用と元の状態用の 2 つのコレクションを保持するようなことはできません。アカウント クラスがシリアライズ可能とマークされていないため、ディープ コピーも実行できません。オブジェクトの種類のため、これを変更することはできません。

アドバイスや洞察を提供できる人に感謝します!

4

1 に答える 1

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 には、コマンドで変更する要素が含まれている必要があります。

2 つの foreach が必要ない場合は、System.Linq 操作を使用できます

于 2013-10-10T10:54:45.673 に答える