将属性从反射传递到表达式

时间:2012-09-06 20:02:21

标签: c# asp.net-mvc reflection lambda

我想使用反射遍历我的模型属性,然后将它们传递给一个期望我的属性为en表达式的方法。

例如,给定此模型:

public class UserModel
{
    public string Name { get; set; }
}

这个验证器类:

public class UserValidator : ValidatorBase<UserModel>
{
    public UserValidator()
    {
        this.RuleFor(m => m.Username);
    }
}

我的ValidatorBase类:

public class ValidatorBase<T>
{
    public ValidatorBase()
    {
        foreach (PropertyInfo property in 
                     this.GetType().BaseType
                         .GetGenericArguments()[0]
                         .GetProperties(BindingFlags.Public | BindingFlags.Insance))
        {
            this.RuleFor(m => property); //This line is incorrect!!
        }
    }

    public void RuleFor<TProperty>(Expression<Func<T, TProperty>> expression)
    {
        //Do some stuff here
    }
}

问题在于ValidatorBase()构造函数 - 假设我拥有PropertyInfo我需要的属性,我应该将expression参数传递给RuleFor方法,它就像UserValidator()构造函数中的行一样工作?

或者,我应该使用除PropertyInfo之外的其他内容来使其工作吗?

1 个答案:

答案 0 :(得分:5)

我怀疑你想要:

ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
Expression propertyAccess = Expression.Property(parameter, property);
// Make it easier to call RuleFor without knowing TProperty
dynamic lambda = Expression.Lambda(propertyAccess, parameter);
RuleFor(lambda);

基本上,这是为属性构建表达式树的问题......来自C#4的动态类型仅用于在不通过反射明确地执行此操作的情况下更轻松地调用RuleFor。你当然可以 这样做 - 但你需要获取RuleFor方法,然后用属性类型调用MethodInfo.MakeGenericMethod,然后调用方法。