2011-10-17 4 views
4

は私の例を提供してみましょう:IEnumerable <T>がシーケンスジェネレータまたは真のコレクションであるかどうかを判断する方法はありますか?

public void DoStuff(IEnumerable<T> sequence) 
{ 
    if (/* is lazy sequence */) throw ... 

    // Do stuff... 
} 

そして、私は潜在的に無限のシーケンスを防ぐためにしたい:

は、私は方法があるとします。

編集:

無限のコレクションに対する保護、詳述するとは、唯一の用途です。ジョンが言及したように。あなたは簡単に無限のIListを持つことができます。いい視点ね。

他の用途は、データが潜在的に反復不可能であるかどうかを検出することです。ランダムジェネレータのように。真のコレクションにはすでにデータがあり、それを2回繰り返すことで同じデータが得られます。

+1

さて、 'ICollection '(注:これはまだ無限でも、怠け者かもしれませんが、 "コレクション"です)。 – jason

+2

「真のコレクション」の要件は何ですか? O(1)のランダムアクセス?リンクリストは許可されていますか? File.ReadLinesの結果は真のコレクションですか? – dtb

+0

IEnumerableは、言及されたもの(コレクション対ジェネレータ)によって充足可能なインターフェイスなので、私は「ラスト」を呼び出すようなハックを試みることができますが、それが "ジェネレータ"無限です... – Yahia

答えて

1

イテレータはIEnumerableを<> .RESET()メソッドをサポートしていません:あなたはメッセージで、良いですが非サポート例外を取得

public void DoStuff(IEnumerable<T> sequence) 
{ 
    sequence.Reset(); 
    // etc.. 
} 

を許容され、「指定したメソッドはサポートされていません」。

+1

面白いですが、非常にハッキリですね:-) – Kugel

+3

「これは不可能です!答えはとても人気があります。多分あなたはそれと一緒に行くべきです。 –

+0

@ハンズ+1スヌークと含意の真実。 – Shibumi

5

保証は何もありません。シーケンスがIList<T>を実装しているかどうかは、イテレータブロックの実装を禁止しますが、それでも永遠に続く「仮想」リストであり、他の有限の非イテレータブロックコレクションでも失敗する可能性があります。

あなたが守ろうとしている点では、何をしようとしていても20億のシーケンスが大丈夫でしょうか?あなたがいくつかの "限界"以上になってしまった(しかし遅れている)場合、例外を投げた拡張メソッドはあなたのために働くでしょうか? (テイクのようなものですが、最後に爆発しました)

5

これは不可能です。

IEnumerable APIは、無限であるかどうかをあなたに伝えることはできません。 ICollectionにキャストして、誰かがあなたのものを渡した共通のケースをキャッチしてみることもできますが、それが必要ならば、最初にICollection < ...オブジェクトを取得するのはなぜですか?

関連する問題