如何从 PropertyDescriptor 获取 lambda 表达式

发布于 2024-09-10 20:36:20 字数 390 浏览 6 评论 0原文

我有一些代码可以枚举一个对象并根据其 ValidationAttribute 记录它所具有的任何错误。

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

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

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

有人知道怎么做吗?

I have some code that enumerates over an object and records any errors it has based on its ValidationAttribute(s).

As it finds them I wish to create a collection of a custom class named RuleViolations. The RuleViolation class looks like this:

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. 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.

Does anyone know how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

箜明 2024-09-17 20:36:20

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);

LambdaExpression and PropertyDescriptor site largely in different worlds (much to my initial frustration). LambdaExpression is going to be interested in PropertyInfo, not PropertyDescriptor.

If you have the PropertyInfo, you can construct an Expression via:

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):

PropertyDescriptor prop = ...
ParameterExpression param = Expression.Parameter(prop.ComponentType, "x");
LambdaExpression lambda = Expression.Lambda(
    Expression.Property(param, prop.Name), param);
薄荷→糖丶微凉 2024-09-17 20:36:20

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

PropertyDescriptor d = ...

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

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

A PropertyDescriptor provides the Type the Property is bound to, and the Name of the Property. You should be able to construct a lambda expression from that (untested):

PropertyDescriptor d = ...

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

LambdaExpression result =
    Expression.Lambda(Expression.Property(arg, d.ComponentType, d.Name), arg);
吃颗糖壮壮胆 2024-09-17 20:36:20

PropertyDescriptor 更像是“虚拟”属性。它可能根本没有支持字段,因此除了微不足道的情况之外,所有以前的解决方案都会失败。

但是,属性描述符提供对 get(以及可选的 set)方法的访问。因此,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);

A PropertyDescriptor is more like a "virtual" property. 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. So the exact equivalent of a PropertyDescriptor read access is a 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文