[英]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.