4

I think my understanding of lambda notation is lacking because I do not understand why it is even needed in Razor. For example:

instead of this:

@Html.DisplayFor(modelItem => item.FirstName)

why can't we just have this:

@Html.DisplayFor(item.FirstName)

What is the purpose of the lambda syntax and why do we need to add in all of the extra work of typing out the lambda notation?

Can someone help me to understand why this is needed and what benefit it offers?

M. Smith
  • 345
  • 3
  • 13

2 Answers2

6

The purpose of lambda expression on Razor view is returning value given by model from anonymous function (i.e. nameless function). Take a look on your first example:

@Html.DisplayFor(modelItem => item.FirstName)

would be translated to something like:

@Html.DisplayFor(String Function(Model modelItem) 
{ 
   return item.FirstName; 
})

Here modelItem given as function parameter declared as Model, and return statement as function body to return property value depending on get/set operation.

If we look further to the DisplayFor helper declaration:

public static MvcHtmlString DisplayFor<TModel, TValue>(
    this HtmlHelper<TModel> html,
    Expression<Func<TModel, TValue>> expression,
    string templateName
)

As stated by @SLaks before, expression tree can be parsed as a parameter to generate proper HTML tag into view based from type of your model defined by @model directive instead of executing it.

The second argument, Expression<Func<TModel, TValue>> is a declaration that ensures any given function parameter will always have same type as your model. This way eliminates reflection code that using GetProperty and GetValue required by HTML helper to retrieve given property value at appropriate time with strongly typed model as a benefit.

Here is an example of reflection code inside HTML helper declaration which can be eliminated by lambda syntax:

var model = html.ViewData.Model;
var value = String.Empty;

if (model != null)
{
    var type = typeof(TModel);
    var propertyInfo = type.GetProperty(templateName);
    var propertyValue = propertyInfo.GetValue(model);
    value = propertyValue.ToString();
}

Afterwards, let's examine the second example:

@Html.DisplayFor(item.FirstName) 

Here DisplayFor will use Object as parameter type, consider we can't determine exactly what type should be pre-assigned thus it sets to System.Object. Since the method doesn't provide model definition type as TModel in generic code, the method probably requires reflection when dealing with property value.

Any improvements and suggestions welcome.

References:

https://msdn.microsoft.com/en-us/library/hh833706%28v=vs.118%29.aspx

http://odetocode.com/blogs/scott/archive/2012/11/26/why-all-the-lambdas.aspx

I want to understand the lambda expression in @Html.DisplayFor(modelItem => item.FirstName)

Community
  • 1
  • 1
Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
4

The HtmlHelper methods take an expression tree as a parameter.

This lets them see the actual property that you pass so that they can observe its attributes.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Either way, you're sending the parameter though right? – M. Smith Jul 28 '16 at 19:29
  • Yes, but with an expression tree, you can also see the `PropertyInfo`. Otherwise, they would have no way to consume formatting attributes. – SLaks Jul 28 '16 at 19:41
  • Sorry, but what is PropertyInfo? – M. Smith Jul 28 '16 at 19:51
  • https://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo Learn about Reflection. – SLaks Jul 28 '16 at 20:07
  • What are the real differences between the two code snippets I provided (one with lambda and one without)? – M. Smith Jul 28 '16 at 20:57
  • 3
    If you pass a raw value, the function has no way of knowing what property it comes from. – SLaks Jul 28 '16 at 21:45
  • 1
    @M.Smith `@Html.DisplayFor(item.FirstName)` is the same as `@Html.DisplayFor("First Name")`, how can the method know the property information from a raw string "First Name" ? – Cheng Chen Jul 29 '16 at 03:54
  • @SLaks so in my second code block, where only the value is passed, Html.DisplayFor would not be able to know the [DisplayFormat] information, since it doesn't know the type? If this is correct, then I think I understand the value in including the lambda statement. – M. Smith Jul 29 '16 at 15:14