接受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"
}
这个类似问题的答案给出了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));
}