6

このメソッドがMoreLinqでどのよう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>にあるのはなぜですか? これは、 on anusingを使用するときに考慮すべきことですか?foreachIEnumerable<T>

副次的な質問:このメソッドは正確には何をしますか? ソース シーケンスにアイテムが 1 つだけ含まれていない場合は常にフォールバック アイテムを返しますか?

4

2 に答える 2

11

IEnumerator<T>extendsIDisposableであるため、using ステートメントに含める必要があります。foreachこれを自動的に行います。(非ジェネリックは拡張さIEnumerator れませんIDisposableが、C# コンパイラは依然としてDispose条件付きで呼び出すコードを生成します。これは、C# 1.0 と 1.2 の間の (数少ない) 変更の 1 つで、1.2 は何らかの理由で .NET 1.1 に同梱されているバージョンです。 )

イテレータ ブロックのコンテキストでこれが重要である理由を説明する記事を次に示します。

メソッドの機能については、次のとおりです。

  • シーケンスが空の場合、フォールバック アイテムを返します
  • シーケンスに項目が 1 つだけある場合は、それを返します
  • シーケンスに複数の項目がある場合は、例外をスローします

PS: MoreLinq が注目を集めているのを見てうれしいです :)

于 2009-06-02T10:45:42.640 に答える
0

Dispose が呼び出されない場合、一部の列挙子は正しく動作しません。これは、一般的なものと同様に非一般的なものにも当てはまります (非一般的なものでは、コードが Dispose 呼び出しをダックタイプするか、IDisposable にキャストしてから IDisposable.Dispose を呼び出す必要があります)。IEnumerator オブジェクトが確実に破棄されるようにすることは、習慣としてはよいことです。不明なタイプの IEnumerable を受け入れるルーチンの正確さのために必要だと思います。

于 2011-04-03T18:04:44.357 に答える