Normally in lamda a expression such as
(x => x.FirstName)
the lamda would return the value of "FirstName" (presumably a string) but some how
@Html.TextBoxFor(x => x.FirstName)
knows that I am referring to the property "FirstName" and not the value returned by FirstName. What C# or compiler technique is being used for achieve this? I tried reading through the MVC source code but it went over my head.
Asked
Active
Viewed 44 times
0
-
I don't understand what you're asking here? – stuartd Oct 25 '19 at 23:46
-
1Simply put, it parses the lambda expression to see what property is being referenced. – John Wu Oct 25 '19 at 23:46
-
TextBoxFor receives an Expression, rather than a Func ( https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.html.inputextensions.textboxfor?view=aspnet-mvc-5.2) .. checkout this answer https://stackoverflow.com/questions/793571/why-would-you-use-expressionfunct-rather-than-funct on func vs expression – KMoussa Oct 25 '19 at 23:54
-
This sort of question makes me think this is an [XY Problem](https://meta.stackexchange.com/q/66377/226912). Is there a different problem you're having and are attempting to handle by implementing this behavior? And are thus looking for guidance in that respect? – Brett Caswell Oct 25 '19 at 23:55
-
I am new to ASP.Net MVC and while reading a chapter on helper methods I couldn't wrap my head around how the compiler was determining the difference between the reference to the property vs it's return value. John Wu's answer below fixed me right up. – Oct 26 '19 at 01:21
1 Answers
0
An Expression
is just an object representing what is contained in the lambda expression. It can be inspected like any other object. You can think of it as a complicated sort of Reflection, and indeed you can get things like Type
and PropertyInfo
for anything inside it, if you know how to parse it.
This example demonstrates how a simple expression like m => m.FirstName
can be parsed to find out what property is being referenced:
public class MyModel
{
public string FirstName { get { return "John Jacob Jingleheimer Schmidt"; } }
}
public class Program
{
public static void Main()
{
var model = new MyModel();
var result = Test(m => m.FirstName, model);
Console.WriteLine(result);
}
public static TOut Test<TIn, TOut>(Expression<Func<TIn, TOut>> expression, TIn instance) where TOut: class
{
MemberExpression memberExpression = (MemberExpression)expression.Body;
var member = memberExpression.Member;
Console.WriteLine("The expression is a reference to '{0}.{1}'", member.DeclaringType.FullName, member.Name);
var compiled = expression.Compile();
var result = compiled(instance) as TOut;
return result;
}
}
Output:
The expression is a reference to 'Example.MyModel.FirstName'
John Jacob Jingleheimer Schmidt

John Wu
- 50,556
- 8
- 44
- 80
-
Thank you, I was missing that the lamba was inside an Expression object and how Expression object works. – Oct 26 '19 at 01:23