【问题标题】:Explaining yield keyword in C#解释 C# 中的 yield 关键字
【发布时间】:2023-03-05 15:18:01
【问题描述】:

您能解释一下“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”上,它会告诉我“获取枚举器当前位置的元素”。

【问题讨论】:

    标签: c#


    【解决方案1】:

    MSDN 的日子:

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


    简单来说:

    yield return 返回 Collection of Object 而不是返回 single 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 语句(将控制流传递给调用方法),然后是 在下一次迭代中通过“goto”到 yield 语句 foreach 循环。

    【讨论】:

      【解决方案2】:

      来自 MSDocs:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-06
        • 2011-06-08
        • 2014-09-27
        • 2018-12-20
        相关资源
        最近更新 更多