c# - 动态生成 LINQ(成员)表达式

标签 c# linq generics

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

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

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

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

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

在验证我的 View 模型之前,我生成了表达式。

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

我错过了什么?

最佳答案

我不得不改变方法调用

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

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

我的猜测

Xamarin.Forms 使用可移植类库 (PCL)。似乎没有实现转换泛型表达式的功能。

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

更新

我无法转换通用表达式。似乎这是不可能的。您需要在返回之前显式转换表达式。

https://dotnetfiddle.net/ufNId4

关于c# - 动态生成 LINQ(成员)表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41692802/

相关文章:

c# - 复杂的 "Contains"字符串比较

C# 非常慢的 StreamReader

c# - 在 Docker 中获取文件

c# - GroupBy 的 LINQ 错误

c# - 将参数替换为表达式

c# - 如果两个字符串都包含值,则需要连接两个字符串;如果第一个字符串为 NULL,则返回一个值

swift - XCTAssert 在 Swift 中使用泛型方法

c# - Web API 响应时间

c# - 告诉调用者 `async Task<T>`方法可能返回null

swift - 返回类型为 Self 而不是 Array 的 CollectionType 扩展