C#:using ステートメントの IEnumerator<T>
-
06-09-2019 - |
質問
どのようにして起こるのか興味がありました SingleOrFallback
メソッドが実装されました もっとリンク そして、これまで見たことのないものを発見しました。
public static T SingleOrFallback<T>(this IEnumerable<T> source, Func<T> fallback)
{
source.ThrowIfNull("source");
fallback.ThrowIfNull("fallback");
using (IEnumerator<T> iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
return fallback();
}
T first = iterator.Current;
if (iterator.MoveNext())
{
throw new InvalidOperationException();
}
return first;
}
}
なぜ、 IEnumerator<T>
で using
声明?を使用するときにこれを考慮する必要がありますか? foreach
で IEnumerable<T>
また?
補足質問: この方法は具体的に何をするのでしょうか?ソース シーケンスに項目が 1 つだけ含まれていない場合は常にフォールバック項目を返しますか?
解決
IEnumerator<T>
伸びる IDisposable
, 、だからあなたは すべき using ステートメントに含めます。 foreach
これは自動的に行われます。(非ジェネリック IEnumerator
しません 伸ばす IDisposable
ただし、C# コンパイラは引き続き呼び出すコードを生成します。 Dispose
条件付きで。これは、C# 1.0 と 1.2 の間の (数少ない) 変更の 1 つでした (何らかの理由で、1.2 は .NET 1.1 に同梱されているバージョンです)。
ここに記事があります これが反復子ブロックのコンテキストにおいてなぜ重要であるかを説明します。
このメソッドが何をするかというと、次のとおりです。
- シーケンスが空の場合は、フォールバック項目を返します
- シーケンスに項目が 1 つだけある場合は、それを返します
- シーケンスに複数の項目がある場合は、例外をスローします。
追伸:MoreLinq が注目を集めているのは嬉しいですね :)
他のヒント
いくつかの列挙子はひどく動作します。これは一般的なもの(非ジェネリックのものがそのコードのいずれかのアヒル型のDisposeの呼び出しを必要とするか、または他のIDisposableインターにキャストし、その後IDisposable.Disposeを呼び出す)などの非ジェネリックのもののために同じように当てはまります。 IEnumeratorをオブジェクトが配置され得ることを保証するために、習慣の問題として良いです。私は未知のタイプのIEnumerableをを受け入れるすべてのルーチンの正確さに関して、それは必要な検討する。