我很想知道如何在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"
}
答案 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));
}