3

デリゲートを受け取り、そのデリゲートをループで実行するメソッドを作成しようとしています。これはそれほど難しいことではありません。たとえば、次のようになります。

public static void RunInLoop<T>(IEnumerable<T> someCollection, 
                                 Action<T> action)
{           
        foreach (var item in someCollection)
        {
                action(item);
        }
}

RunInLoopただし、のようなことを行う手段をユーザーに提供したいとします。breakつまり、ループの実行を停止します(または単にから戻るRunInLoop)。

私が考えたこと:

  1. -というメソッドを作成します。これは(プライベート)例外をスローし、try catchでBreak()囲み、(プライベート)例外をキャッチした場合は戻るだけです。action(item)デリゲートがキャッチを渡した場合、これはあまり良くありませんException

  2. foreach新しいスレッドでを実行しBreak()、現在のスレッドを強制終了して実装します。他の理由の中でも、UIベースのアプリケーション(Silverlightなど)でメソッドを使用する場合、これは適切ではありません。UIスレッドで実行する必要がある場合があります。

  3. 私が得たもう1つの提案は、各実行の最後に確認するという条件で、追加の代理人を受け取ることでした。breakそれはユーザーにとって直感的ではなく、反復の終わりに制限されるため、私もそれが好きではありません。これが今のところ私の最後の手段です。

だから私はまだ見つけることができた良い解決策はありません。何か提案/方向性はありますか?

4

2 に答える 2

3
public static void RunInLoop<T>(IEnumerable<T> someCollection, 
                                 Func<T, bool> action)
{           
        foreach (var item in someCollection)
        {
                if(action(item))
                     break;
        }
}

「アクション」(この変更を行う場合は名前を func に変更する必要があります) に、続行するかどうかを示すブール値を返すようにします。

元のメソッドは単なるForEach拡張メソッドであることにも言及する価値があります。 これは、Eric Lippertによるブログ投稿で、フレームワークから意図的に除外された理由と、それが本当に良い習慣ではない理由を述べています (とにかく多くの人が使用しています)。

于 2012-05-07T20:39:53.660 に答える
0

ブール値である静的/メンバー変数を使用することはできませんか。

Action
{
    ...
    foreach
        if (!s_KeepGoing)
            break
    ...
}

または、bool を指定する柔軟性が必要な場合は、Action がデリゲートの 2 番目のパラメーターとして bool への参照を取り、上記のように bool をチェックします。

public delegate void MyDelegate<in T>(T type, ref bool keepGoing);

public static void RunInLoop<T>(IEnumerable<T> someCollection, 
                                 MyDelegate<T> action)
{           
        foreach (var item in someCollection)
        {
                action(item, ref s_AnotherKeepGoing);
        }
}
于 2012-05-07T21:48:37.783 に答える