Should IEnumerable Use Profitability for Deferral

Should IEnumerable use Holidays to snooze?

Here is a test code that helped me understand delayed execution and profitability.

//immediate execution public IEnumerable Power(int number, int howManyToShow) { var result = new int[howManyToShow]; result[0] = number; for (int i = 1; i < howManyToShow; i++) result[i] = result[i - 1] * number; return result; } //deferred but eager public IEnumerable PowerYieldEager(int number, int howManyToShow) { var result = new int[howManyToShow]; result[0] = number; for (int i = 1; i < howManyToShow; i++) result[i] = result[i - 1] * number; foreach (var value in result) yield return value; } //deferred and lazy public IEnumerable PowerYieldLazy(int number, int howManyToShow) { int counter = 0; int result = 1; while (counter++ < howManyToShow) { result = result * number; yield return result; } } [Test] public void Power_WhenPass2AndWant8Numbers_ReturnAnEnumerable() { IEnumerable listOfInts = Power(2, 8); foreach (int i in listOfInts) Console.Write("{0} ", i); } [Test] public void PowerYieldEager_WhenPass2AndWant8Numbers_ReturnAnEnumerableOfInts() { //deferred but eager execution IEnumerable listOfInts = PowerYieldEager(2, 8); foreach (int i in listOfInts) Console.Write("{0} ", i); } [Test] public void PowerYield_WhenPass2AndWant8Numbers_ReturnAnEnumerableOfIntsOneAtATime() { //deferred and lazy execution IEnumerable listOfInts = PowerYieldLazy(2, 8); foreach (int i in listOfInts) Console.Write("{0} ", i); } 
+6
source share
3 answers

No need to use yield - in the end, you can do everything yield by writing a custom counter ( IEnumerator[<T>] ) and delaying the action until the first MoveNext() . However, it is quite difficult to implement. Of course, if you do use yield , the implementation is delayed by default (you can make it non-delayed using two methods - those that do not use yield , which then after accessing the data uses another method (iterator block) to implement the enumerator.

Honestly, writing enumerators is difficult and difficult. I avoid this if absolutely necessary. The Iterator blocks are great.

+6
source

A function (F1) that returns IEnumerable can return an IEnumerable computed in another function (F2), if F2 is deferred, then F1 is deferred

for example, in the following code, both F1 and F2 are deferred

 public IEnumerable<int> F2() { for (int i = 0; i < 10; i++) { yield return i; } } public IEnumerable<int> F1() { return F2(); } 
+1
source

Delayed and impatient opposites - lazy - is simply a synonym for delayed.

An expected sequence is one that is precomputed, such as a list or an array. A delayed sequence is one that is calculated whenever it repeats.

In your examples, Power impatient because it evaluates the array and returns it. This is different from PowerYieldEager , which does not create an array until the resulting IEnumerable is repeated.

You can think of the delayed and impatient as the possible existence of a sequence, and not the content of the sequence. With that in mind, yield return is just one way to defer; any sequence calculated by querying for results is a pending sequence.

0
source

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


All Articles