Skip to content

Loops, Lambdas, and Variables #16073

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chanan opened this issue May 4, 2018 · 5 comments
Closed

Loops, Lambdas, and Variables #16073

chanan opened this issue May 4, 2018 · 5 comments
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@chanan
Copy link

chanan commented May 4, 2018

This might be a known Razor issue, and since I haven't used Razor in ages I was caught off guard.

This does not work:

@for (int i = 0; i < items.Count; i++)
{
  <CarouselItem IsActive="@(SecondIndex == i)" src="@item[i].Source" alt="@items[i].Alt">
    <h5>@items[0].Header</h5>
  </CarouselItem>
}

You get an exception with the h5 line (the previous lines are fine):

Uncaught Error: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
  at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) <0x1f27f48 + 0x00018> in <140509c0d46c421ca83585ed625d5577>:0 
  at Sample.Pages.Carousels+<>c__DisplayClass0_0.<BuildRenderTree>b__10 (Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder3) <0x1f3d190 + 0x00090> in <14d8d1e2ea4743fa889b8a5ddf494a58>:0 

The work around is to add a capture variable in the loop like so:

@for (int i = 0; i < items.Count; i++)
{
  Item item = items[i];
  <CarouselItem IsActive="@(SecondIndex == i)" src="@item.Source" alt="@item.Alt">
    <h5>@item.Header</h5>
  </CarouselItem>
}

Like I said not sure if this is fixable since it might be in Razor like that, but at the very least a better error message and adding this to the docs would be helpful.

@figloalds
Copy link

In your first block of code you have this line

<h5>@item[0].Header</h5>

which seems to reference an array item (as opposed to items) that is apparently not anywhere else aforementioned.

@dlr1
Copy link

dlr1 commented May 4, 2018

try this. you would need to use local variable for it to work

@for (int i = 0; i < items.Count; i++)
{
var local_i = i;
  <CarouselItem IsActive="@(SecondIndex == local_i)" src="@item[local_i].Source" alt="@items[local_i].Alt">
    <h5>@item[0].Header</h5>
  </CarouselItem>
}

@chanan
Copy link
Author

chanan commented May 4, 2018

@felyperennan That was a typo when copying and pasting into the issue.
@dlr1 Thanks, but that is basically the same as my workaround :) Anyway, point being if it is something that can't be fixed because it is in Razor, I just think it should be noted in the docs, I happened to remember that issue from my C#/Razor days, but a newbie wouldnt know that.

@dlr1
Copy link

dlr1 commented May 4, 2018

I opened a similar one aspnet/Blazor#665

@SteveSandersonMS
Copy link
Member

This is a general C# question about how loops and lambda hoisting interact. The answer is that foreach is different from for, in that for conceptually defines a new loop variable for each iteration, whereas for does not (it's the same variable across all iterations). Please see C# docs for more about this.

@mkArtakMSFT mkArtakMSFT transferred this issue from dotnet/blazor Oct 27, 2019
@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Oct 27, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

5 participants