接受lambda的方法的实现

时间:2015-08-31 21:01:19

标签: c# asp.net-mvc lambda

我很想知道如何在MVC中实现接受lambda表达式的LabelFor,EditorFor ...方法。

假设我有一个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"

  }

2 个答案:

答案 0 :(得分:2)

This answer对类似的问题给出了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中的属性。

答案 1 :(得分:-2)

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