NOTE
This question was asked in regards to the Blazor @bind
feature. As it turns out @bind
is just a delegate underneath (see the documentation), so it follows the same behaviour as delegates. See some of the other posts for a description of this.
I am building a table in which the number of rows depends on the number of elements in an array on a model. Each row should then bind to a value in the equivalent row of the array. Like this:
@for(int i = 0; i < round.PlayerScore.Length; i++)
{
<tr>
<th scope="row">@(i+1)</th>
<td class="col-xs-1"><input id="name" @bind="round.PlayerScore[i]"
</tr>
}
Problem is that this doesn't work. If I use i
as index in the binding, I get an error. I need to first store i as seperate variable, for it to work, like such:
@for(int i = 0; i < round.PlayerScore.Length; i++)
{
int local = i;
<tr>
<th scope="row">@(i+1)</th>
<td class="col-xs-1"><input id="name" @bind="round.PlayerScore[local]"
</tr>
}
The same thing is described in this github issue, but the conclusion is that it is the intended behaviour. One of the comments state that:
My understanding is that in C# for loops the same variable is reused (so all your lambda functions reference the length of your list).
In your workaround you are declaring a new variable each iteration which is the way C# requires lambdas to be written.
...but I don't really get what this means. When I print i+1
it correctly prints the numbers from 1 to 18 (if the array has length 18), so i
seems to contain the correct value. Also, I cannot see it be anything but an int
, since this is how it's initialised.
So why do I have to use a local placeholder (local
) instead of the loop iterator (i
)?