質問

どのようにして起こるのか興味がありました 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 声明?を使用するときにこれを考慮する必要がありますか? foreachIEnumerable<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をを受け入れるすべてのルーチンの正確さに関して、それは必要な検討する。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top