如何从PropertyDescriptor获取lambda表达式

问题描述 投票:2回答:3

我有一些代码枚举一个对象,并根据其ValidationAttribute(s)记录它所发生的任何错误。

找到它们后,我希望创建一个名为RuleViolations的自定义类的集合。 RuleViolation类如下所示:

public string           Message  { get; set; }
public LambdaExpression Property { get; set; }

Property是lambda表达式,因此该属性不必是字符串。当我手动添加错误时,此方法起作用,但是当我只有属性的PropertyDescriptor对象时,我不确定如何指定LambdaExpression。

有人知道吗?

c# asp.net-mvc data-annotations
3个回答
5
投票

LambdaExpression和PropertyDescriptor网站很大程度上位于不同的世界(这让我很沮丧)。 LambdaExpression将对PropertyInfo感兴趣,而不是PropertyDescriptor。

如果有PropertyInfo,则可以通过以下方式构造一个表达式:

PropertyInfo prop = ...
ParameterExpression param = Expression.Parameter(prop.ReflectedType, "x");
LambdaExpression lambda = Expression.Lambda(
    Expression.Property(param, prop), param);

可以还会尝试按名称解析,但这一定一样,尤其是如果您使用的是自定义类型模型(ICustomTypeDescriptor等):

PropertyDescriptor prop = ...
ParameterExpression param = Expression.Parameter(prop.ComponentType, "x");
LambdaExpression lambda = Expression.Lambda(
    Expression.Property(param, prop.Name), param);

3
投票

PropertyDescriptor提供属性绑定到的Type以及属性的名称。您应该能够从中构造一个lambda表达式(未经测试):

PropertyDescriptor d = ...

Expression arg = Expression.Parameter(d.ComponentType, "arg");

LambdaExpression result =
    Expression.Lambda(Expression.Property(arg, d.ComponentType, d.Name), arg);

0
投票

PropertyDescriptor更像是“虚拟”属性。它可能根本没有后备字段,因此所有以前的解决方案都将失败,除非是琐碎的情况。

但是,属性描述符提供对get(和可选的设置)方法的访问。因此,a PropertyDescriptor读取访问权限]的确切等同项是MethodCallExpression

static readonly MethodInfo PropertyDescriptorGetter =
   typeof(PropertyDescriptor).GetMethod(nameof(PropertyDescriptor.GetValue));

PropertyDescriptor prop = ...;
ParameterExpression param = Expression.Parameter(prop.ComponentType, "x");
MethodCallExpression value = Expression.Call(prop, PropertyDescriptorGetter, param);
LambdaExpression lambda = Expression.Lambda(value, param);
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.