70

このコード サンプルでは、​​catch ブロックから外側のループを続行する方法はありますか?

while
{
   // outer loop

   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           continue;
       }
   }
}
4

10 に答える 10

118

更新: この質問は、この主題に関する私の記事のインスピレーションでした。素晴らしい質問をありがとう!


「continue」と「break」は、「goto」の快適な構文にすぎません。どうやら、それらにかわいい名前を付けて、特定の制御構造への使用を制限することで、「すべての goto は常にすべて悪い」群衆の怒りをもはや引き付けません。

やりたいことが外側への継続である場合、外側のループの上部にラベルを定義してから、そのラベルに「移動」するだけです。そうしてもコードの理解が妨げられないと思われる場合は、それが最も適切な解決策かもしれません。

ただし、これを機会として、制御フローがリファクタリングの恩恵を受けるかどうかを検討します。ネストされたループに条件付きの「中断」と「継続」があるときはいつでも、リファクタリングを検討します。

検討:

successfulCandidate = null;
foreach(var candidate in candidates)
{
  foreach(var criterion in criteria)
  {
    if (!candidate.Meets(criterion))
    {  // TODO: no point in continuing checking criteria.
       // TODO: Somehow "continue" outer loop to check next candidate
    }
  }
  successfulCandidate = candidate;
  break;
}
if (successfulCandidate != null) // do something

2 つのリファクタリング手法:

まず、内側のループをメソッドに抽出します。

foreach(var candidate in candidates)
{
  if (MeetsCriteria(candidate, criteria))
  { 
      successfulCandidate = candidate;
      break;
  }
}

第二に、すべてのループを排除できるか? 何かを検索しようとしてループしている場合は、それをクエリにリファクタリングします。

var results = from candidate in candidates 
              where criteria.All(criterion=>candidate.Meets(criterion))
              select candidate;
var successfulCandidate = results.FirstOrDefault();
if (successfulCandidate != null)
{
  do something with the candidate
}

ループがない場合は、中断または続行する必要はありません。

于 2009-07-15T19:40:02.057 に答える
40
    while
    {
       // outer loop

       while
       {
           // inner loop
           try
           {
               throw;
           }
           catch 
           {
               // how do I continue on the outer loop from here?
               goto REPEAT;
           }
       }
       // end of outer loop
REPEAT: 
       // some statement or ; 
    }

問題が解決しました。(なに?? なんでみんなそんな汚い顔してるの?)

于 2009-07-15T19:43:49.210 に答える
23

休憩を使用できます。声明。

while
{
   while
   {
       try
       {
           throw;
       }
       catch 
       {
           break;
       }
   }
}

Continue は、現在のループの先頭に戻るために使用されます。

それよりも多くのレベルを分割する必要がある場合は、何らかの「if」を追加するか、恐ろしい/推奨されない「goto」を使用する必要があります。

于 2009-07-15T19:23:26.287 に答える
9

内部の while ループで try/catch 構造を交換します。

while {
  try {
    while {
      throw;
    }
  }
  catch {
    continue;
  }
}
于 2009-07-15T19:22:00.237 に答える
5

いいえ
、内側のループを別のメソッドに抽出することをお勧めします。

while
{
   // outer loop
       try
       {
           myMethodWithWhileLoopThatThrowsException()
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           continue;
       }
   }
}
于 2009-07-15T19:23:13.430 に答える
3

break内側のループで使用します。

于 2009-07-15T19:23:37.080 に答える
0
using System;

namespace Examples
{

    public class Continue : Exception { }
    public class Break : Exception { }

    public class NestedLoop
    {
        static public void ContinueOnParentLoopLevel()
        {
            while(true)
            try {
               // outer loop

               while(true)
               {
                   // inner loop

                   try
                   {
                       throw new Exception("Bali mu mamata");
                   }
                   catch (Exception)
                   {
                       // how do I continue on the outer loop from here?

                       throw new Continue();
                   }
               }
            } catch (Continue) {
                   continue;
            }
        } 
    }

}

}
于 2009-07-23T15:37:08.233 に答える
0

外側に続く内側から抜け出したいだけです。

while
{
   // outer loop

   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           break;
       }
   }
}
于 2009-07-15T19:24:17.033 に答える
-1

これを実現する最善の方法は、 breakステートメントを使用することだと思います。Breakは現在のループを終了し、終了した場所から実行を継続します。この場合、内側のループが終了し、外側の while ループに戻ります。コードは次のようになります。

while
{
   // outer loop

   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // break jumps to outer loop, ends inner loop immediately.
           break; //THIS IS THE BREAK
       }
   }
}

それがあなたが達成しようとしていたことだと思いますよね?ありがとう!

于 2009-07-15T19:35:32.610 に答える
-3

MyException など、独自の例外タイプを使用します。それで:

while
{
   try {
   // outer loop
   while
   {
       // inner loop
       try
       {
           throw;
       }
       catch 
       {
           // how do I continue on the outer loop from here?
           throw MyException;
       }
   }
   } catch(MyException)
   { ; }
}

これは、ネストされた while ステートメントのいくつかのレベルを継続および解除するために機能します。フォーマットが悪くてすみません;)

于 2009-07-15T19:41:41.850 に答える