62

I want to do something like this:

from a in stuff
let counter = 0
select new { count = counter++, a.Name };

But I get a error telling me that counter is read only. Is there a way to do something similar to this, without declaring a variable outside of the query?

Basically, I just want to show a count/index column in LINQPad (which is awesome, BTW), which means I can't declare counter ahead of time.

Mike Pateras
  • 14,715
  • 30
  • 97
  • 137

3 Answers3

145

Rather than using side-effects, use the overload of Select which takes an index:

stuff.Select((value, index) => new { index, value.Name });

You could do it using side-effects, but not in the way you tried:

int counter = 0;
var query = from a in stuff
            select new { count = counter++, a.Name };

I would strongly advise against this though.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Unfortunately, this does not (always) work with entity framework core row sets. A workaround would be to stick these rows in a List first. – Wolfgang Grinfeld Jul 09 '19 at 07:32
  • Please explain why you strongly advise against this – tjmoore Sep 07 '21 at 16:51
  • 1
    @tjmoore: Because LINQ is designed for pipelines without side-effects. For example, the query I've given at the end will not do anything in itself. That just sets up the pipeline - you have to *use* the query in order for it to count anything... and if will count every time you iterate over `query`. That kind of thing can be really confusing in the real world (as opposed to trivial examples) – Jon Skeet Sep 07 '21 at 17:01
  • Thanks, works, but remember, it CANNOT BE PERFORMED ON QUERYABLES, only Array, List etc. will work :) – Arekadiusz Aug 31 '22 at 12:40
8

If you truly want it to be a counter, and not just an index, then just move the counter declaration outside the LINQ expression

var counter = 0;
from a in stuff
select new { count = counter++; a.Name };
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Another answer strongly advises against this. http://stackoverflow.com/a/2209014/7724 – bzlm Jul 07 '16 at 20:57
2

Just add two variable here NumberRow is for that

.Select((x,NumberRow) => new ViewModelArchiveOrder
                    {
                        NumberRow= NumberRow + 1,
                    })
CAmador
  • 1,881
  • 1
  • 11
  • 19
saeed bagheri
  • 121
  • 1
  • 4