注: 下部の編集を参照してください。私はばかです。
タグ名のセットを処理し、新しいものを識別/処理する次のコードがありました。
IEnumberable<string> tagNames = GetTagNames();
List<Tag> allTags = GetAllTags();
var newTagNames = tagNames.Where(n => !allTags.Any(t => t.Name == n));
foreach (var tagName in newTagNames)
{
// ...
}
...そしてこれはうまくいきましたが、「Foo」というタグがあり、リストに「foo」が含まれている場合を処理できませんでした。つまり、大文字と小文字を区別しない比較を行っていませんでした。
次のように、大文字と小文字を区別しない比較を使用するようにテストを変更しました。
var newTagNames = tagNames.Where(n => !allTags.Any(t => t.Name.Equals(n, StringComparison.InvariantCultureIgnoreCase)));
...そして突然、foreach が実行された (そして MoveNext が呼び出された) newTagNames のときに例外がスローされます。例外は言う:
シーケンスに要素がありません
私はこれに混乱しています。foreach
シーケンスが空でないことを主張するのはなぜですか? を呼び出している場合はそのエラーが表示されると予想されますが、 ?First()
を使用している場合はそうではありません。foreach
編集:詳細。
これは分ごとに奇妙になっています。私のコードは非同期メソッドであり、私は迷信的であるため、例外が発生したポイントと、例外がキャッチされて報告されるポイントとの間に「距離」がありすぎると判断しました。そのため、スローされた例外が実際に私が思っていたものであることを確認するために、問題のあるコードの周りに try/catch を配置しました。
これで、デバッガーで foreach 行までステップ実行し、シーケンスが空であることを確認し、デバッガーが "in" という単語を強調表示するビットまでステップアップできます。もう 1 ステップで、例外ハンドラーに入ります。
しかし、先ほど追加した例外ハンドラではありません。最近追加されたものにアクセスせずに、最も外側の例外ハンドラーに着陸します! 一致catch (Exception ex)
しませんし、プレーンとも一致しませんcatch
。(私も入れましたfinally
、そしてそれが途中でそれを訪問することを確認しました)。
私は常に、これらのような例外ハンドラーが例外をキャッチすると信じてきました。私は今怖いです。大人が必要です。
編集2:
わかりました、そうです、誤報です...例外は、私が考えていたコードによって発生していなかったという理由だけで、ローカルのtry/catchによってキャッチされていませんでした。上で述べたように、デバッガーでの実行がforeach
ストレートの「in」から外側の例外ハンドラーにジャンプするのを見たので、エラーが発生した場所であるという私の (間違った) 仮定。ただし、空の列挙では、それは単に関数内で実行された最後のステートメントであり、何らかの理由で、デバッガーは関数からのステップアウトまたは呼び出し時点での次のステートメントの実行を表示しませんでした。実際にエラーを引き起こしたもの。
回答してくれたすべての人に謝罪し、私がばかだと言って回答を作成したい場合は、喜んで受け入れます. つまり、またSOに顔を出したら…