9

次のコードがある場合:

List<MyClass> list = GetList();
list.ForEach(i => i.SomeMethod());

SomeMethod()そして、例外をスローするとしましょう。繰り返しますかForEach、それともそこで止まりますか?

終了した場合、コレクション内の残りのアイテムを取得してメソッドを実行する方法はありますか?

4

3 に答える 3

14

はい、例外がスローされた場合、ループは終了します。その動作が望ましくない場合は、デリゲートに例外処理を配置する必要があります。このためのラッパー メソッドを簡単に作成できます。

public static Action<T> SuppressExceptions<T>(Action<T> action)
{
    return item =>
    {
        try
        {
            action(item);
        }
        catch (Exception e)
        {
            // Log it, presumably
        }
    };
}

正直なところ、可能であればこれを避けたいと思います。そのようなすべての例外をキャッチするのは不快です。また、失敗したアイテムや例外なども記録しません。要件についてもっと詳しく考える必要があります。

  • 失敗したアイテムを収集する必要がありますか?
  • 例外を収集する必要がありますか?
  • どの例外をキャッチしますか?

foreach代わりに通常のループを使用し、エラーを処理してエラーを収集する別のメソッドを作成する方が、ほぼ確実にクリーンになります。個人的には、一般的にforeachoverを使用することを好みます。これに関する Eric Lippert の考えもForEach読みたいと思うかもしれません。

于 2012-05-17T06:02:12.913 に答える
4

エラーがスローされます。また、 の再実装も順調に進んでいますforeach。ちょうどどうですか:

foreach (var item in list)
{
    try
    {
        // dangerous thing with item
    }
    catch (Exception e)
    {
        // how do you want to log this?
    }
}

これには、ほとんどのバージョンの .NET で動作し、明らかに副作用があるという利点があります。もちろん、このコードをForEachデリゲートに直接入れることもできますが、(ラムダ関数ではなく) メソッド自体になる場合にのみお勧めします。


合理的な代替手段は、ForEachWithCatchすべての例外をキャプチャして呼び出し元に送り返す独自の拡張機能を作成することです。

public static IEnumerable<Tuple<T,Exception>> ForEachWithCatch<T>(this IEnumerable<T> items, Action<T> action)
{
    var exceptions = new List<Tuple<T,Exception>>();

    foreach(var item in items)
    {
        try
        {
            action(item);
        }
        catch(Exception e)
        {
            exceptions.Add(Tuple.Create(item, e));
        }
    }

    return exceptions;
}

これにより、失敗した各項目の列挙型とそれに対応する例外が返されます。

于 2012-05-17T06:03:19.010 に答える
0

SomeMethodtry-catchブロックを実装している場合、 foreachは続行されます

void SomeMethod()
{
  try
  {
    //Some operation on i 
  }
  catch(Exception ex)
  {
  }
}

しかし、そうでない場合、foreachは壊れます。

それを行うことの1つはこの方法です

list.ForEach(i => 
     {
         try
         {
             i.SomeMethod();
         }
         catch(Exception ex)
         {
         }
     });

ただし、コードにtry-catchブロックをゼロにすることは常に良いことです。そうでなければ、犯人がどこにいるのかを見つけることはできません。

于 2012-05-17T06:18:23.853 に答える