访问收益率收益

时间:2014-07-08 11:51:25

标签: c# generator

是否有办法在构建IEnumerable<T>本身的方法中循环访问由yield return构建的IEnumerable集合?

愚蠢的例子:

Random random = new Random();

IEnumerable<int> UniqueRandomIntegers(int n, int max)
{
    while ([RETURN_VALUE].Count() < n)
    {
        int value = random.Next(max);
        if (![RETURN_VALUE].Contains(value))
            yield return value;
    }
}

1 个答案:

答案 0 :(得分:5)

没有建立集合。返回的序列是懒惰地评估的,除非调用者明确地将数据复制到另一个集合,否则它将在获取后立即消失。

如果你想确保独特性,你需要自己做。例如:

IEnumerable<int> UniqueRandomIntegers(int n, int max)
{
    HashSet<int> returned = new HashSet<int>();
    for (int i = 0; i < n; i++)
    {
        int candidate;
        do
        {
            candidate = random.Next(max);
        } while (returned.Contains(candidate));
        yield return candidate;
        returned.Add(candidate);
    }
}

唯一随机整数的另一种替代方法是构建max项的集合并对其进行洗牌,这仍然可以及时完成。在maxn相似的情况下(因为您不需要循环直到您有幸获得新项目),这会更有效,但在{ {1}}非常大且max不是。

编辑:如评论中所述,您可以通过将n循环的正文更改为:

来略微缩短
for

如果项目中已存在该项目,int candidate; do { candidate = random.Next(max); } while (!returned.Add(candidate)) yield return candidate; 将返回Add这一事实。