Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementation of method accepting lambda

I'm interested to understand how are implemented LabelFor, EditorFor... methods that accept lambda expressions in MVC.

Lets say I have a class Person and I want to print the name and the value of a property. How must be implemented Label() and Editor() methods?

  class Person
  {
     public int Id { get; set; }
  }

  void Label(Expression<Func<Person, int>> expression)
  {
     //...
  }

  void Editor(Expression<Func<Person, int>> expression)
  {
     //...
  }

  public void Test()
  {
     Person p = new Person
     {
        Id = 42
     };

     Label(x => x.Id );  // print "Id"
     Editor(x => x.Id); // print "42"

  }
like image 630
albert Avatar asked Jan 18 '26 04:01

albert


1 Answers

This answer to a similar question gives an implementation of Label. The code's by Josh Smith in the PropertyObserver class of his MVVM foundation:

    private static string GetPropertyName
        (Expression<Func<TPropertySource, object>> expression)
    {
        var lambda = expression as LambdaExpression;
        MemberExpression memberExpression;
        if (lambda.Body is UnaryExpression)
        {
            var unaryExpression = lambda.Body as UnaryExpression;
            memberExpression = unaryExpression.Operand as MemberExpression;
        }
        else
        {
            memberExpression = lambda.Body as MemberExpression;
        }

        Debug.Assert(memberExpression != null, 
           "Please provide a lambda expression like 'n => n.PropertyName'");

        if (memberExpression != null)
        {
            var propertyInfo = memberExpression.Member as PropertyInfo;

            return propertyInfo.Name;
        }

        return null;
    }

It works by looking at the expression tree and checking for the name of the property in member expressions.


For Editor, you can use a similar strategy of looking through the Expression to find out what you need about the property. What exactly to do depends a lot on what info you want.

The specific way you asked it where all you want is the value of a property from a Person, you can simplify a lot. I also added a Person parameter, since you seem to want the value for a given person.

int Editor(Person person, Func<Person, int> expression)
{
    return expression(person);
}

This can be used like Editor(p, p => p.Id);. Note that I changed Expression<Func<Person, int>> to Func<Person, int>, which means that instead of an expression tree it gets a Func. You can't examine a Func to find names of properties and such, but you can still use it to find the property from the Person.

like image 134
31eee384 Avatar answered Jan 19 '26 18:01

31eee384



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!