Reputation: 3127
I'm converting one list to another. Additionally to data from first list I want to have position added. To do this I created following code:
class A
{
...
}
class B
{
...
public int Position { get; set; }
}
List<A> listA = ...;
int pos = 1;
List<B> listB = listA.Where(...).Take(...).Select(
a => new B { ..., Position = pos++ }).ToList();
It this working, but should it and will it always work?
Is it safe to use such variable like pos
in my code and change its value inside LINQ's Select
?
Upvotes: 2
Views: 1052
Reputation: 68660
You don't need pos
. Select
has an overload that takes a Func<T, int, TResult>
as an argument, instead of Func<T, TResult>
, where the int is the index of the element T
.
listA.Select(
(a, index) => new B { ..., Position = index}
).ToList();
Is it safe to use such variable like pos in my code and change its value inside LINQ's Select
In your concrete case, it is safe, mainly because you realize the list immediately (using ToList
).
Generally, I'd advise against this. Here's why:
var collection = listA.Where(...).Take(...).Select(
a => new B { ..., Position = pos++ });
foreach(var item in collection)
Console.WriteLine(item.Position); //prints 0,1,2
foreach(var item in collection)
Console.WriteLine(item.Position); //prints 3,4,5
LINQ is stateless. It's supposed to be pure, as in, for the same input, you should always get the same output. By making the lambda dependent on a mutable variable, you're giving up this very important property.
Upvotes: 6