-6

I have an IEnumerable<List<int>> and I want to insert a value inside one of its Lists. But I can't?
I tried the following statement in LinqPad, but the result set remains unchanged after the Insert:

var lists = new int[]{1,2,3}.Select(x => new List<int>{x});
lists.Dump();
lists.First().Insert(0, 5);
lists.Dump();

(I was expecting the List to contain: {5, 1}, instead it still only contains {1})

Protector one
  • 6,926
  • 5
  • 62
  • 86
  • 3
    Your list is not a list but a query. Whenever you execute it it will generate three lists with a **single** int 1,2 and 3. So you don't get a single list that contains three ints. If you want that use `Enumerable.Range(1, 3).ToList()` or `new int[]{1,2,3}.ToList()` – Tim Schmelter Nov 23 '16 at 12:52
  • 3
    Self-answered questions are good if they cover something that hasn't been covered before, and you're actively encouraged to post them, but in this case, the basic question has been asked before, and received answers that are at least as good as your own. For instance http://stackoverflow.com/questions/9104181/updating-an-item-property-within-ienumerable-but-the-property-doesnt-stay-set –  Nov 23 '16 at 12:55
  • @hvd so it might be ok to post a question and **immediatly** answer it yourself in some cases? – Evk Nov 23 '16 at 13:07
  • @Tim: Ah, yes, that was poor naming on my part. I meant `lists`. I updated my code. – Protector one Nov 23 '16 at 13:29
  • @hvd: You are right, but. I couldn't find the QA you linked to after searching for some of the terms in my question. Probably because this is specifically about `List`. So, I think this is a valid addition to the KB, since it covers a different container than the question you linked. – Protector one Nov 23 '16 at 13:31
  • @Protectorone: well, it wasn't only the naming, look at your last sentence: _"I was expecting the List to contain: {5, 1, 2, 3}, instead it still contains {1, 2, 3}"_ It was simply a wrong expectation and a false statement. – Tim Schmelter Nov 23 '16 at 13:47
  • @Tim: No, no, no, I _mean_ `List` _there_! It always contained Lists! I'm referring to the _First_ `List`, of course. – Protector one Nov 23 '16 at 13:55
  • @Protectorone: ok, then your expectation is wrong anyway because the first list never contains 1,2,3 but only 1. The `Select` is called for every `int` in the array, that's why you get three lists where each list contains only one number. – Tim Schmelter Nov 23 '16 at 13:58
  • @Tim: Ah, you got me there! I modified my question. Mea culpa. – Protector one Nov 23 '16 at 14:01
  • @Protectorone Whether the object in the query is a `List` or not isn't relevant here. The point is simply that the query you have isn't yielding the same objects on each iteration. What those objects are is irrelevant. There are literally an infinite number of possible objects that they could be, but it doesn't matter, the question is the same. – Servy Nov 23 '16 at 14:30
  • @Evk Yes, see http://stackoverflow.com/help/self-answer. –  Nov 23 '16 at 14:48
  • 1
    @Protectorone None of those differences are relevant. It could say, `Foo` instead of `list` or `item`, or `asdfklnasdfn`, or `ImARandomClass`. What the actual item in the sequence is doesn't actually affect the question. If someone does end up finding your question, instead of the canonical, when they have this problem, then they'll see that it's a duplicate, go to the canonical, and get a great answer, because **it's a duplicate question**. That's why we close duplicates questions as duplicates, so that people who find those duplicates get pointed to the canonical answer. – Servy Nov 23 '16 at 16:00

2 Answers2

-1

Yes you can't! The IEnumerable generates new Lists every time it is evaluated; it says so right there in your code:

.Select(x => new List<int>{x});

When you call Dump(), it is evaluated. When you call First(), it's evaluated again. Then Dump again. All new Lists!

If you evaluate the IEnumerable before putting it in the list variable (e.g. by putting it into an array), it would work:

var list = new int[]{1,2,3}.Select(x => new List<int>{x}).ToArray();
list.Dump();
list.First().Insert(0, 5);
list.Dump();
Protector one
  • 6,926
  • 5
  • 62
  • 86
-5

As said by Tim Schmelter in the first comment at your OP, a Linq IEnumerable reference it is a "query", namely it is a sort of reference to some static methods (eventually chained among them), that get a IEnumerable object(s).

So, what you are really calling, it isn't an object reference, but something that work as a static methods reference of an IEnumerable object.. so you executes that static methods every time you use your linq reference after its declaration in your code.

Therefore, if you instatiate an object in the original "query" expression you cannot modify its status with some "status changing" properties of the enumerated objects getted by the query, you are changing only the values getted in that precise time that you executes that property, but the immediately next call of the "query" reference in the code will shows/elaborates always the original expression and so will instantiate always the same object in the declaration of the query expression.

Anyway, you may try this:

var list = new int[]{1,2,3}.Select(x => new List<int>{x});
list = new int[]{5}.First().Concat(list);

In this way you can reassign the same reference with a query that instantiate a new object with the value as you want cancatening this value with the values getted by the original referenced query, and so you have changed the original object status intantiated in the initial query.

Ciro Corvino
  • 2,038
  • 5
  • 20
  • 33