简体   繁体   English

如何从 PropertyDescriptor 获取 lambda 表达式

[英]How to get a lambda expression from a PropertyDescriptor

I have some code that enumerates over an object and records any errors it has based on its ValidationAttribute(s).我有一些代码可以枚举对象并根据其 ValidationAttribute(s) 记录它的任何错误。

As it finds them I wish to create a collection of a custom class named RuleViolations.当它找到它们时,我希望创建一个名为 RuleViolations 的自定义类的集合。 The RuleViolation class looks like this: RuleViolation 类如下所示:

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

Property is a lambda expression so that the property doesn't have to be a string.属性是一个 lambda 表达式,因此属性不必是字符串。 THis works when I manually add errors but I'm not sure how to specify the LambdaExpression when all I have is the property's PropertyDescriptor object.这在我手动添加错误时有效,但当我只有属性的 PropertyDescriptor 对象时,我不确定如何指定 LambdaExpression。

Does anyone know how?有谁知道怎么做?

LambdaExpression and PropertyDescriptor site largely in different worlds (much to my initial frustration). LambdaExpression 和 PropertyDescriptor 站点主要位于不同的世界(这让我最初很沮丧)。 LambdaExpression is going to be interested in PropertyInfo, not PropertyDescriptor. LambdaExpression 将对 PropertyInfo 感兴趣,而不是 PropertyDescriptor。

If you have the PropertyInfo, you can construct an Expression via:如果您有 PropertyInfo,则可以通过以下方式构建表达式:

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

You can also attempt to resolve by name, but this is not necessarily the same, especially if you are using a custom type model ( ICustomTypeDescriptor etc):您也可以尝试通过名称来解决,但这不一定是相同的,特别是如果你使用的是自定义类型模型( ICustomTypeDescriptor等):

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

A PropertyDescriptor provides the Type the Property is bound to, and the Name of the Property. PropertyDescriptor 提供属性绑定到的类型和属性的名称。 You should be able to construct a lambda expression from that (untested):您应该能够从中构造一个 lambda 表达式(未经测试):

PropertyDescriptor d = ...

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

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

A PropertyDescriptor is more like a "virtual" property. PropertyDescriptor更像是一个“虚拟”属性。 It may not have a backing field at all, so all previous solutions will fail except for trivial cases.它可能根本没有支持字段,因此除了微不足道的情况外,所有以前的解决方案都将失败。

However, a property descritor provides access to a get (and optionally set) method.但是,属性描述符提供对 get(和可选的 set)方法的访问。 So the exact equivalent of a PropertyDescriptor read access is a MethodCallExpression .因此,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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM