web-dev-qa-db-ja.com

C#でのforeachループのデバッグ:これはどのような反復ですか?

デバッグ変数を設定し、foreachを開始するたびにインクリメントする以外に、Visual Studioデバッガーを接続した状態で侵入したときに、これがループのX回目であることを確認する方法はありますか?

これは、コンパイルされたコードに追加されるものではなく、どちらかといえばVisualStudioの機能になると思います。

34
Matt

これがあなたが探しているもののように見える前のスタックオーバーフローの質問です: get-index-of-current-foreach-iteration

そのリンクから引用された回答:

Foreachは、IEnumerableを実装するコレクションを反復処理するためのものです。これは、コレクションでGetEnumeratorを呼び出すことによって行われます。これにより、列挙子が返されます。

この列挙子には、メソッドとプロパティがあります。

  • MoveNext()
  • 電流

Currentは、列挙子が現在存在するオブジェクトを返し、MoveNextはCurrentを次のオブジェクトに更新します。

明らかに、インデックスの概念は列挙の概念とは異質であり、実行することはできません。

そのため、ほとんどのコレクションは、インデクサーとforループ構造を使用してトラバースできます。

この状況では、ローカル変数を使用してインデックスを追跡するよりも、forループを使用する方が非常に好きです。

7
jumpdart

ループ内にブレークポイントを設定し、ブレークポイントを右クリックして条件を設定します。右クリックしてデバッグ中のヒット数を確認し、必要に応じてリセットすることもできます。ブレークポイントがヒットしたときに評価されるブール式を設定して、条件付きでブレークする(または単に渡す)ことができます。

23

GaroYeriazarianの答えを拡張して...

再コンパイルせずにすばやく汚い方法。コード例:

    var ints = new[] {5, 6, 0, 1};

    foreach (var i in ints)
    {
        Debug.WriteLine(100 / i);
    }

ループの前とループ内にブレークポイントを1つずつ追加します。最初のヒットがヒットし、カウントを開始する場合は、ヒットカウント条件を設定します。

two breakpoints

大きなヒットカウント条件を設定し、カウンターをリセットして続行します。その後、例外などが発生したときに、「現在のヒット数」を再度確認できます。

Hit count dialog

13
johv

Visual StudioのImmediate Windowを使用することもできます。これにより、デバッグ中にスコープ内の任意の変数に対してC#式を記述できます。次のように、List.IndexOf()メソッドを使用します。

querying the foreach iteration index in the Immediate Window

7
Jeremy Deal

ブレークポイントのヒット数を使用できる可能性があります。正確にはあなたが望むものではありませんが、役に立つかもしれません。

また、この場合にforループを使用したくない重大な理由があります。

5
Incognito

6年後の2017年2月の更新-下記の拡張機能は現在 OzCode と呼ばれています。この機能は現在 Foresee と呼ばれていますが、VS2013でのみサポートされています。

また、これは非常に便利な機能であると感じたので、BugAidと呼ばれるVisualStudioデバッグエクスペリエンス用に作成した商用拡張機能の一部として作成しました。

拡張機能は、foreachループ内にいるときはいつでも、どの反復であるかを正確に示します。 Foreach Buttons

[Iteration x of y]ボタンをクリックすると、新しいウィンドウが表示され、アイテムの完全なリストが表示され、ループ内の現在の場所が強調表示されます(このリストは、デバッガーでコレクションを評価する場合にのみ表示されます。副作用を引き起こさない)。

Foreach Visualizationウィンドウを開いたら、次のアイテムのいずれかを右クリックして[Skip to Item]を選択し、そのアイテムにヒットするまで前に進むことができます(これにより、手動で設定してヒットカウントをいじる必要がなくなります。ブレークポイント):

Using Skip To Iteratioon

4
Omer Raviv

あなたのコードが

_foreach (String line in lines){
    Console.WriteLine(line);//breakpoint here
}
_

ブレークポイントをforeachループ内に置き、「イミディエイトウィンドウ」を起動して、次のコードを実行しますArray.IndexOf(lines, line);

3
user961954

これが私がそれを行う方法です[VS2017で]:

  1. Foreachループ内にブレークポイントを設定します
  2. ブレークポイントを右クリックして、「アクション」を選択します
  3. テキストボックスに次のように入力します。$FUNCTION {list.Items.IndexOf(item)}ここで、「list」はリストの名前、「item」は現在のアイテムです。
  4. コードの実行を続行し、出力ウィンドウを確認します
3
brandonstrong

デバッグでアサーションを使用してみましたか?デバッガーは、コード内のその正確なポイントで起動されます。
例えば: System.Diagnostics.Debug.Assert(myValue> = 0)

2
user353283

反復しているものがIndexOf()メソッドをサポートしている場合は、デバッグ変数を設定する必要はありません。

この例のように:

foreach (var i in myList)
{
    reportprogress(myList, i);

    //Do stuff
}

private void reportprogress<T>(List<T> l, T i)
{
    progressBar1.Value = ((l.IndexOf(i)) * 100) / l.Count;
    Application.DoEvents();
}
0
Luiscencio