0

https://dotnetfiddle.net/QHd0Rr#

I'm trying to populate a simple IEnumerable but I'm getting an error:

Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at Program.Main()
Command terminated by signal 6



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

public class Program
{
    public static void Main()
    {
        var key1 = new WidgetA{Id = 1, Key = 52};
        var key2 = new WidgetA{Id = 1, Key = 102};
        var key3 = new WidgetA{Id = 1, Key = 152};
        IEnumerable<WidgetA> list = Enumerable.Empty<WidgetA>();
        list.Append(key1);
        list.Append(key2);
        list.Append(key3);
        
        Console.WriteLine(list.ToList()[0]);
    }
}

public class WidgetA
{
    public int Id { get; set; }

    public int Key { get; set; }

    public string ValueToGet { get; set; }
}
Rod
  • 14,529
  • 31
  • 118
  • 230
  • 2
    Question why you dont populate a list instead? What is your use case? – aloisdg Oct 17 '22 at 17:02
  • I need to update the Enumerable several times after this step before I convert it to a list – Rod Oct 17 '22 at 17:03
  • 1
    `Enumerable.Empty` returns an empty `Array` - A FIXED length of zero. https://stackoverflow.com/a/33364039/463206 – radarbob Oct 17 '22 at 17:10

2 Answers2

5

Enumerable.Append<> is a lazy Linq function. If this is how you want to use it, you need to store the intermediate result:

    IEnumerable<WidgetA> list = Enumerable.Empty<WidgetA>();
    list = list.Append(key1);
    list = list.Append(key2);
    list = list.Append(key3);
Blindy
  • 65,249
  • 10
  • 91
  • 131
  • Shrug, who am I to stand in the way of a potential mad genius? – Blindy Oct 17 '22 at 17:24
  • How do you update an item in the Enumerable? – Rod Oct 17 '22 at 18:09
  • 2
    @Rod ???? Have you seen `IEnumerable` interface? Did you found *any* "update" methods there? Very unclear what you are asking with that comment. – Alexei Levenkov Oct 17 '22 at 18:14
  • @Blindy can you help me understand why the code is like that? – Rod Oct 18 '22 at 15:55
  • That's just how Linq works. What you're building here is essentially a linked list of single-element enumerables, to be iterated later. Very inefficient, but if that's what you want, this is how you do it. – Blindy Oct 18 '22 at 17:38
1

While I really like (and upvoted) Blindy's answer and I think that it may better fit your need, here is an alternative with yield return:

public static void Main()
{
    IEnumerable<int> list = DoStuff();
    list.Dump();
}

public static IEnumerable<int> DoStuff()
{
    yield return 0;
    yield return 1;
    // enter code here or whatever
    yield return 2;
    yield return 3;
    yield return 4;
}
aloisdg
  • 22,270
  • 6
  • 85
  • 105