C #: how to translate the return keyword

  • What will the MSDN sample look like without the yield keyword? You can use any example if you transfer. I just wanted to understand what is happening under the hood.
  • Is the yield statement calculated impatiently or lazy ?

Example:

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

If the profitability operator is eagerly evaluated, then this is my guess:

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

I do not know how this might look if a lazy operator is lazily evaluated.

Update: Reflector gives the following:

 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; } 
+4
source share
4 answers

In the good old days, before we had a yield statement, we used to write classes that implemented 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; } } } 

Or something like that. It wasn’t fun, let me tell you.

+7
source

First, profitability is not an operator. profitability and profitability are statements.

There are many articles on how the compiler implements iterator blocks. Start by reading the C # specification on iterator blocks; he gives some suggestions on how a C # developer might want to think about it.

Next, read the Raymond Chen series "Implementing Iterators in C # and Its Implications"

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

Next, read the chapter of John Skeet on:

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

If you're still interested, read my series on design factors that came with this feature:

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

+11
source
  • This would be a regular implementation of IEnumerable<T> , without relying on an existing implementation such as List<T>
  • Lazy.

Further information is available here .

0
source
  • Let the .NET Reflector decompile it. This is a general solution (actually a machine in fact), but rather complicated,> 20 lines of code, if I remember correctly.
  • Lazy. That yield can be quite effective.
0
source

Source: https://habr.com/ru/post/902502/


All Articles