C#:如何翻译收益关键字

  • 如果没有yield关键字,MSDN示例将会是什么样子? 如果你喜欢,你可以使用任何示例。 我只想了解发生了什么。
  • 收益运营商进行热切懒惰的评估?
  • 样品:

    using System;
    using System.Collections;
    public class List
    {
        public static IEnumerable Power(int number, int exponent)
        {
            int counter = 0;
            int result = 1;
            while (counter++ < exponent)
            {
                result = result * number;
                yield return result;
            }
        }
    
        static void Main()
        {
            // Display powers of 2 up to the exponent 8:
            foreach (int i in Power(2, 8))
            {
                Console.Write("{0} ", i);
            }
        }
    }
    
  • MSDN - 收益关键字

  • 如果收益运营商在这里受到热切评估,那么我的猜测是:

        public static IEnumerable Power(int number, int exponent)
        {
            int counter = 0;
            int result = 1;
            List<int> powers;
            while (counter++ < exponent)
            {
                result = result * number;
                powers.add(result);
            }
            return powers;
        }
    

    我不知道如果收益运营商是懒惰评估,它可能会是什么样子。

    更新:反射器给出了这个:

    public class List
    {
        // Methods
        public List();
        private static void Main();
        public static IEnumerable Power(int number, int exponent);
    
        // Nested Types
        [CompilerGenerated]
        private sealed class <Power>d__0 : IEnumerable<object>, IEnumerable, IEnumerator<object>, IEnumerator, IDisposable
        {
            // Fields
            private int <>1__state;
            private object <>2__current;
            public int <>3__exponent;
            public int <>3__number;
            private int <>l__initialThreadId;
            public int <counter>5__1;
            public int <result>5__2;
            public int exponent;
            public int number;
    
            // Methods
            [DebuggerHidden]
            public <Power>d__0(int <>1__state);
            private bool MoveNext();
            [DebuggerHidden]
            IEnumerator<object> IEnumerable<object>.GetEnumerator();
            [DebuggerHidden]
            IEnumerator IEnumerable.GetEnumerator();
            [DebuggerHidden]
            void IEnumerator.Reset();
            void IDisposable.Dispose();
    
            // Properties
            object IEnumerator<object>.Current { [DebuggerHidden] get; }
            object IEnumerator.Current { [DebuggerHidden] get; }
        }
    }
    
    IEnumerator<object> IEnumerable<object>.GetEnumerator()
    {
        List.<Power>d__0 d__;
        if ((Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -2))
        {
            this.<>1__state = 0;
            d__ = this;
        }
        else
        {
            d__ = new List.<Power>d__0(0);
        }
        d__.number = this.<>3__number;
        d__.exponent = this.<>3__exponent;
        return d__;
    }
    
    
    
    private bool MoveNext()
    {
        switch (this.<>1__state)
        {
            case 0:
                this.<>1__state = -1;
                this.<counter>5__1 = 0;
                this.<result>5__2 = 1;
                while (this.<counter>5__1++ < this.exponent)
                {
                    this.<result>5__2 *= this.number;
                    this.<>2__current = this.<result>5__2;
                    this.<>1__state = 1;
                    return true;
                Label_0065:
                    this.<>1__state = -1;
                }
                break;
    
            case 1:
                goto Label_0065;
        }
        return false;
    }
    

    早在我们拥有yield运算符之前,我们就习惯编写实现IEnumerator的类。

    class PowerEnumerator : IEnumerator<int>
    {
      private int _number;
      private int _exponent;
      private int _current = 1;
    
      public PowerEnumerator(int number, int exponent)
      {
        _number = number;
        _exponent = exponent;
      }
    
      public bool MoveNext()
      {
        _current *= number;
        return _exponent-- > 0;
      }
    
      public int Current
      {
        get
        {
          if (_exponent < 0) throw new InvalidOperationException();
          return _current;
        }
      }
    }
    

    或类似的东西。 这不好玩,让我告诉你。


    首先,收益率不是运营商。 收益率收益率和收益率收益率是报表

    有很多关于编译器如何实现迭代器块的文章。 首先阅读关于迭代器块的C#规范部分; 它提供了一些关于C#的实现者可能想如何去做的建议。

    接下来阅读Raymond Chen的系列文章“C#中迭代器的实现及其后果”

    http://www.bing.com/search?q=raymond+chen+the+implementation+of+iterators

    接下来,请阅读Jon Skeet关于这个主题的书籍章节:

    http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

    如果毕竟您仍然感兴趣,那么请阅读我的系列文章,了解该功能的设计因素:

    http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/


  • 让.NET Reflector反编译它。 这是一个通用的解决方案(实际上是一个状态机),但是如果我没有记错的话,它会非常复杂,> 20行代码。
  • 懒。 这就是为什么yield可以非常高效的问题。
  • 链接地址: http://www.djcxy.com/p/54311.html

    上一篇: C#: How to translate the Yield Keyword

    下一篇: How yield works in c#