1

I understand the general idea of what deferred execution is in terms of a collection, but...in the context of .NET, what does that have in common with reconstructing the same elements of a collection over and over again, instead of reading from a cache? Deferred execution is supposed to be about delaying the execution until it's actually necessary, sometimes allowing the program to forgo populating later elements in a collection if they're not needed and other optimizations like that. However, take the following example:

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        IEnumerable<NestedType> tests = GetTestCases();
        foreach (NestedType test in tests)
        {
            Console.WriteLine(test.Value);
            test.Value = "x";
            Console.WriteLine(test.Value);
        }

        foreach (NestedType test in tests)
        {
            Console.WriteLine(test.Value);
        }
    }

    private static IEnumerable<NestedType> GetTestCases()
    {
        return new[] {"a", "b", "c"}.Select(x => new NestedType {Value = x});
    }

    private class NestedType
    {
        internal string Value { get; set; }
    }
}

The IEnumerable<NestedType> that is returned by GenerateTests is using deferred execution, but as it turns out, this doesn't only mean that it's waiting until an element in that collection is being accessed before running the lambda to compute it; it also means that it is running the lambda to re-compute and recreate the same exact elements it has already gone over. (Not the same elements in a completely literal sense, but they're still in the same "slots" of the collection.)

These two concepts seem very separate. Why were they put together like this? What does deferring execution of a function until it's needed have in common with refusing to read from a cache? Even if other elements aren't being accessed yet, why aren't the elements that have been accessed being stored consistently in an internal array or something and re-read?

What advantages/disadvantages does this have, and how does it affect coding in .NET?

Panzercrisis
  • 4,590
  • 6
  • 46
  • 85
  • @GertArnold I edited the question. It wasn't meant in a completely literal way. – Panzercrisis Nov 07 '17 at 20:31
  • @GetArnold Wow, I didn't see something earlier. I'll fix the code real fast to show what I was originally dealing with. I minimized it a little too much. – Panzercrisis Nov 07 '17 at 20:34
  • Okay, it's done. – Panzercrisis Nov 07 '17 at 20:35
  • 3
    It's not "refusing to read from a cache" - there is no cache. There aren't two concepts here, just one: deferred execution. The *lack* of an automatic cache is not a "concept", it's the lack of one - it's the default. Deferred execution doesn't imply a cache. – Blorgbeard Nov 07 '17 at 20:42
  • 1
    I don't have time to write an answer for you now but it might help to think of the IEnumerable as instructions for generating the collection rather than a collection itself. An obvious disadvantage with the way you are using it (multiple enumeration) is that the collection is generated multiple times, if that is an expensive operation you obviously pay for it more than once. You might want to look into Lazy for an option for run-once deferred execution. (If I have time tonight I might write up a full answer.) – Mr.Mindor Nov 07 '17 at 21:00
  • "sometimes allowing the program to forgo populating later elements in a collection if they're not needed and other optimizations like that" - No, that's not true at all. What makes you think that? – Enigmativity Nov 07 '17 at 21:51
  • There are no "deferred execution is in terms of a collection" - collections **do not** have deferred execution. In your example only the LINQ operators (like `.Select`) have deferred execution. – Enigmativity Nov 07 '17 at 21:54

0 Answers0