有没有办法确定IEnumerable <t>是序列生成器还是真正的集合?</t>

时间:2011-10-17 16:05:58

标签: c# linq

让我举个例子:

假设我有一个方法:

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

    // Do stuff...
}

我想防范潜在的无限序列。

编辑:

详细说明,防范无限集合只是其中一种用途。正如乔恩所说。你可以轻松拥有无限的IList。好点。

其他用途可能是检测数据是否可能无法重复。像一个随机发电机。真正的集合已经在内存中存储了数据,并且迭代它两次会给我相同的数据。

3 个答案:

答案 0 :(得分:5)

没有任何保证,没有。您可以看到序列是否也实现了IList<T> - 这将禁止迭代器块实现,但仍然可以是一个永远持续的“虚拟”列表,并且对于其他一些有限的非迭代器块集合也会失败。

就你想要保护的内容而言,一个20亿长的序列是否可以用于你想要做的事情?如果你最终获得超过一些“限制”(但是这样懒得)的扩展方法会引发异常吗? (像Take这样的东西,但最后会爆炸。)

答案 1 :(得分:5)

这是不可能的。

IEnumerable API无法告诉您它是否是无限的。您可以尝试将其转换为ICollection,以捕捉有人通过其中一个的常见情况,但如果这是您想要的,那么为什么不采取ICollection&lt; ...&gt;首先是对象?

答案 2 :(得分:1)

迭代器不支持IEnumerable&lt;&gt; .Reset()方法:

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

你得到一个NotSupportedException,这是好的,消息“不支持指定的方法”,这是可以容忍的。