views:

79

answers:

2

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?

+3  A: 

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);
dtb
Thanks for the info. I'm closer I think. Can you check my updated code?
I fixed my mistake. Thank you.
+4  A: 

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);
Marc Gravell
Why is the lambda argument of type `PropertyType` and not `ComponentType`? If you construct a lambda `(X x) => x.Y` then X is the type of the object the property is declared on, and the return type of the lambda is the type of the property, or not?
dtb
@dtb - indeed; typo
Marc Gravell
Thanks for the tip about PropertyInfo. I've updated my code but am getting an exception. Can you see where I went wrong?
nm. I see my mistake. Thank you.