访问yield return集合

本文关键字:集合 return yield 访问 | 更新日期: 2023-09-27 18:12:01

是否有任何方法可以从构建IEnumerable本身的方法内访问yield return在循环中构建的IEnumerable<T>集合?

愚蠢的例子:

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;
    }
}

访问yield return集合

没有正在建立的集合。返回的序列是惰性求值的,除非调用者显式地将数据复制到另一个集合,否则它将在获取后立即消失。

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

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相似的情况下更有效(因为你不需要循环,直到你足够幸运地获得一个新项目),但在max非常大而n不是的情况下效率很低。

编辑:正如评论中所指出的,您可以通过将for循环的主体更改为: 来略微缩短此内容。
int candidate;
do
{
    candidate = random.Next(max);
} while (!returned.Add(candidate))
yield return candidate;

使用了这样一个事实,即如果项目已经存在于集合中,Add将返回false