0

你能解释一下'yield'关键字在Enumerable方面是如何工作的吗?例如。我不明白下面程序的代码如何返回 IEnumerable 类型的对象:

class Program
    {
        static IEnumerable<T> Merge<T>(IEnumerable<T> left, IEnumerable<T> right)
            where T: IComparable<T>
        {
            IEnumerator<T> l = left.GetEnumerator();
            IEnumerator<T> r = right.GetEnumerator();

            bool l_has_data = l.MoveNext();
            bool r_has_data = r.MoveNext();

            while (l_has_data || r_has_data)
            {
                if (!l_has_data && r_has_data)
                {
                    yield return r.Current;
                    r_has_data = r.MoveNext();
                    continue;
                }
                if (!r_has_data && l_has_data)
                {
                    yield return l.Current;
                    l_has_data = l.MoveNext();
                    continue;
                }

                int comp = l.Current.CompareTo(r.Current);
                if (comp < 0)
                {
                    yield return l.Current;
                    l_has_data = l.MoveNext();
                }
                else if (comp > 0)
                {
                    yield return r.Current;
                    r_has_data = r.MoveNext();
                }
                else
                {
                    yield return l.Current;
                    yield return r.Current;
                    l_has_data = l.MoveNext();
                    r_has_data = r.MoveNext();
                }
            }
        }

如果我将鼠标悬停在“.Current”上,它会告诉我这“获取枚举器当前位置的元素”。

4

2 回答 2

3

什么 MSDN 天:

yield 关键字向编译器发出信号,表明它出现的方法是一个迭代器块。编译器生成一个类来实现迭代器块中表达的行为。在迭代器块中,yield 关键字与 return 关键字一起使用,为枚举器对象提供值。例如,这是在 foreach 语句的每个循环中返回的值。


简单来说:

yield return返回 aCollection of Object而不是返回 asingle object

    static void Main(string[] args)
    {

        int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        // supposed u need to find all the numbers which are greater then 5
        // in general it could have been done like

        foreach (int number in numbers)
        {
            if (number > 5)
            {
                Console.WriteLine(number);
            }

        }

        // what if u needed the numbers that are greater then 5 multiple times, each time you would have to start a loop
        // yield return helps to return a collection of int
        var needed_numbers = NeededNumbers(numbers);

        foreach (int neededNumber in needed_numbers)
        {
            Console.WriteLine(neededNumber);
        }
    }

    private static IEnumerable<int> NeededNumbers(int[] nums)
    {
        foreach (int number in nums)
        {
            if (number > 5)
            {
                yield return number;
            }

        }
    }

引自 DotNetPerls

yield return 语句在语义上等价于 return 语句(将控制流传递给调用方法),然后在 foreach 循环的下一次迭代中对 yield 语句进行“goto”。

于 2013-02-16T05:43:32.727 回答
1

来自 MS Docs

在语句中使用 yield 上下文关键字时,表明它出现的方法、运算符或 get 访问器是迭代器。当您为自定义集合类型实现 IEnumerable 和 IEnumerator 模式时,使用 yield 定义迭代器无需显式的额外类(保存枚举状态的类,请参见 IEnumerator 示例)。

于 2019-01-02T14:39:12.840 回答