动态生成LINQ(成员)表达式

时间:2017-01-17 08:57:58

标签: c# linq generics

我正在使用FluentValidation来验证Xamarin.Forms中的表单项。这些项目的定义来自外部。因此,我不知道我需要在我的视图模型上验证哪些属性。

RuleFor(viewmodel => viewmodel.Description).NotEmpty();

我的想法是,在运行时动态生成这些表达式。

我在验证器中创建了一个List来存储这些表达式。

public List<Expression<Func<IViewModel, object>>> RequiredFieldExpressions
    = new List<Expression<Func<IViewModel, object>>>();

在验证我的viewmodel之前,我会生成表达式。

var tmpMethod = typeof(TypeHelper).GetRuntimeMethod("GetExpression", new Type[] { typeof(string) });
var tmpGeneric = tmpMethod.MakeGenericMethod(myViewModel.GetType(), typeof(string));
var tmpInvokeResult = tmpGeneric.Invoke(null, new object[] {coreObjectPropertyName});

创建表达式的方法:

public static Expression<Func<T, TProperty>> GetExpression<T, TProperty>(string inPropertyName) where T : IViewModel
{
    var tmpPropertyInfo = typeof(T).GetRuntimeProperties().First(p => p.Name == inPropertyName);

    var tmpEntityParam = Expression.Parameter(typeof(T), "type");
    Expression tmpExpression = Expression.Property(tmpEntityParam, tmpPropertyInfo);

    if (tmpPropertyInfo.PropertyType != typeof(TProperty))
    {
        tmpExpression = Expression.Convert(tmpExpression, typeof(TProperty));
    }
    return Expression.Lambda<Func<T, TProperty>>(tmpExpression, tmpEntityParam);
}

现在应该创建验证规则的行会抛出一个无效的强制转换异常。

// Cast not valid
RuleFor((Expression<Func<IViewModel, object>>) tmpInvokeResult).NotEmpty();

我错过了什么?

1 个答案:

答案 0 :(得分:0)

我必须从

更改方法调用
var tmpGeneric = tmpMethod.MakeGenericMethod(myViewModel.GetType(), typeof(string));

var tmpGeneric = tmpMethod.MakeGenericMethod(myViewModel.GetType(), typeof(object));

我的猜测

Xamarin.Forms使用便携式类库(PCL)。似乎没有实现强制通用表达式的功能。

如果有人可以验证这一点,那就太好了。

<强>更新

我无法投射通用表达式。看起来似乎不可能。您需要在返回表达式之前显式转换它。

https://dotnetfiddle.net/ufNId4