接受lambda的方法的实现

本文关键字:实现 方法 接受 lambda | 更新日期: 2023-09-27 18:10:46

我有兴趣了解如何实现LabelFor, EditorFor…在MVC中接受lambda表达式。

假设我有一个Person类,我想打印一个属性的名称和值。如何实现Label()和Editor()方法?

  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"
  }

接受lambda的方法的实现

这个类似问题的答案给出了Label的实现。代码由Josh Smith在他的MVVM基础的PropertyObserver类中编写:

    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;
    }

它通过查看表达式树并检查成员表达式中属性的名称来工作。


对于Editor,您可以使用类似的策略查看Expression以找出您需要的属性。具体怎么做在很大程度上取决于你想要什么信息。

您询问它的具体方式是您想要的是Person的属性值,您可以简化批次。我还添加了一个Person参数,因为您似乎想要给定人的值。

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

可以像Editor(p, p => p.Id);一样使用。注意,我将Expression<Func<Person, int>>更改为Func<Person, int>,这意味着它得到的不是表达式树,而是Func。您不能检查Func来查找属性的名称等,但是您仍然可以使用它从Person中查找属性。

void Label(Expression<Func<Person, int>> expression)
{
    Person myPerson = new Person { Id = 42 };
    foreach (PropertyInfo prop in typeof(Person).GetProperties())
        if(prop.Equals(expression(myPerson))) print(prop.Name);
}
void Editor(Expression<Func<Person, int>> expression)
{
    Person myPerson = new Person { Id = 42 };
    print(expression(myPerson));
}