8

foreachforeach 自体の状態でループ中に壊れるループがあります。try catch例外をスローしてからループを続行するアイテムへの方法はありますか?

これは、例外がヒットして終了するまで数回実行されます。

try {
  foreach(b in bees) { //exception is in this line
     string += b;
  }
} catch {
   //error
}

例外は foreach の条件にあるため、これはまったく実行されません

foreach(b in bees) { //exception is in this line
   try {
      string += b;
   } catch {
     //error
   }
}

これがどのように起こっているのかを尋ねる人もいることを知っているので、これを次に示します。 a (私の例では b) が(ミツバチ)に見つからないPrincipalOperationExceptionため、例外がスローされています。PrincipalGroupPrincipal

編集:以下のコードを追加しました。また、あるグループ メンバーが存在しないドメインを指していることもわかりました。メンバーを削除することでこれを簡単に修正しましたが、私の質問はまだ残っています。foreach の条件内でスローされた例外をどのように処理しますか?

PrincipalContext ctx = new PrincipalContext(ContextType.domain);
GroupPrincipal gp1 = GroupPrincipal.FindByIdentity(ctx, "gp1");
GroupPrincipal gp2 = GroupPrincipal.FindByIdentity(ctx, "gp2");

var principals = gp1.Members.Union(gp2.Members);

foreach(Principal principal in principals) { //error is here
   //do stuff
}
4

2 に答える 2

5

@Guillaumeからの回答とほぼ同じですが、「私は私の方が好きです」:

public static class Extensions
{
    public static IEnumerable<T> TryForEach<T>(this IEnumerable<T> sequence, Action<Exception> handler)
    {
        if (sequence == null)
        {
            throw new ArgumentNullException("sequence");
        }

        if (handler == null)
        {
            throw new ArgumentNullException("handler");
        }

        var mover = sequence.GetEnumerator();
        bool more;
        try
        {
            more = mover.MoveNext();
        }
        catch (Exception e)
        {
            handler(e);
            yield break;
        }

        while (more)
        {
            yield return mover.Current;
            try
            {
                more = mover.MoveNext();
            }
            catch (Exception e)
            {
                handler(e);
                yield break;
            }
        }
    }
}
于 2012-09-21T13:48:06.327 に答える
4

たぶん、そのようなメソッドを作成しようとすることができます:

    public IEnumerable<T> TryForEach<T>(IEnumerable<T> list, Action executeCatch)
    {
        if (list == null) { executeCatch(); }
        IEnumerator<T> enumerator = list.GetEnumerator();
        bool success = false;

        do
        {
            try
            {
                success = enumerator.MoveNext();
            }
            catch
            {
                executeCatch();
                success = false;
            }

            if (success)
            {
                T item = enumerator.Current;
                yield return item;
            }
        } while (success);
    }

次のように使用できます。

        foreach (var bee in TryForEach(bees.GetMembers(), () => { Console.WriteLine("Error!"); }))
        {
        }
于 2012-09-21T03:54:35.493 に答える