简体   繁体   中英

Understanding lambda in razor/blazor

I am very new to razor syntax & C# generally, and I am just working through a few blazor courses and got stuck getting my head around the use of a lambda in one of the examples (here for ref https://docs.microsoft.com/en-us/aspnet/core/tutorials/build-your-first-blazor-app?view=aspnetcore-3.1#build-a-todo-list

this bit:

<h3>Todo (@todos.Count(todo => !todo.IsDone))</h3>

The whole code is below... my problem is that I understand that it is evaluating whether members of the todos list are true/false, and then putting the count of these onto the page, and also that todo is a local variable within the Lambda (because if I change it to todoxxx =>.todoxxx.IsDone it still works).

What I don't understand is how it is checking each entry in the todos list to evaluate it?

I apologise profusely in advance for what is probably a very simple question!

@page "/todo"

<h3>Todo (@todos.Count(todo => !todo.IsDone))</h3>

<ul>
    @foreach (var todo in todos)
    {
        <li>
            <input type="checkbox" @bind="todo.IsDone" />
            <input @bind="todo.Title" />
        </li>
    }
</ul>

<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>

@code {
    private IList<TodoItem> todos = new List<TodoItem>();
    private string newTodo;

    private void AddTodo()
    {
        if (!string.IsNullOrWhiteSpace(newTodo))
        {
            todos.Add(new TodoItem { Title = newTodo });
            newTodo = string.Empty;
        }
    }
}

If you look at the source code for the IEnumerable.Count , you will see that, behind the scenes, it does exactly that:

  • Runs a foreach loop on the collection;
  • Tests your lambda code against every collection member;
  • If lambda results in true then the counter variable is incremented;
  • In the end, it returns the counter value.

In this particular context, your lambda is essentially treated like a function pointer, only this time with a strongly defined interface: it takes a single parameter of whatever type you have in your collection, and returns bool .

Regarding where the System.Linq reference comes from and how it is resolved without an explicit @using , it seems that Razor components are actually partial classes, with their other parts "hidden" (meaning autogenerated by the compiler). For your particular example, if you go to the \obj\Debug\netcoreapp3.1\Razor\Pages folder in your project, you will find there a file named "Todo.razor.g.cs", which contains the following:

namespace BlazorApp1.Pages
{
    #line hidden
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Components;
...
    [Microsoft.AspNetCore.Components.RouteAttribute("/todo")]
    public partial class Todo : Microsoft.AspNetCore.Components.ComponentBase
    {
    ...
    }
}

Which means that these 5 namespaces are always available in all components, regardless of the _Imports.razor contents. Not sure why these particular ones have been chosen, that's probably a question for Microsoft.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM