【问题标题】:Turn a property name as a string into a Linq Expression将属性名称作为字符串转换为 Linq 表达式
【发布时间】:2013-08-01 13:42:21
【问题描述】:

我需要将表示接口上的属性名称的字符串转换为表达式。我已经完成了大部分工作,最后只有一件我无法弄清楚。

 static Expression<Func<T, int>> MakeGetter<T>(string propertyName)
    {
         var input = Expression.Parameter(typeof(T));
         var property = typeof(T).GetProperty(propertyName) ??
                                   GetProperty(propertyName, typeof(T));

         var expr = Expression.Property(input, property);
         var propType = property.PropertyType.Name;

         switch (propType.ToLower())
         {
              case "string":
                   return Expression.Lambda<Func<T, string>>(expr, input);
              case "int":
                   return Expression.Lambda<Func<T, int>>(expr, input);
         }
  }

  private static PropertyInfo GetProperty(string propertyName, Type i)
  {
       var baseInterfaces = i.GetInterfaces();
       foreach (var baseInterface in baseInterfaces)
       {
            var property = baseInterface.GetProperty(propertyName);
            return property ?? GetProperty(propertyName, baseInterface);
       }
       return null;
  }

我遇到的一个问题是在 MakeGetter 函数的末尾,我不知道该函数是字符串还是 int 或其他类型,并且在我完成所有反射之前无法知道,所以如何创建此方法,使其具有通用性并正确返回表达式。

【问题讨论】:

  • 有什么理由不想使用Expression.Property(input, propertyName)
  • 我需要生成类似于 Expression > 的东西
  • 但是你的方法被声明为返回Expression&lt;Func&lt;T, int&gt;&gt;...如果你需要它在输入输出中都是通用的,你需要有两个类型参数。
  • 我明白了,但这就是我遇到的问题。我需要生成那个表达式,但我不知道表达式输出类型是什么,直到反射发生并且我可以看到属性类型?
  • 您打算如何使用 MakeGetter?我假设您在按名称调用时不知道属性类型? Func&lt;T, object&gt;?

标签: c# linq expression


【解决方案1】:

查看here 在运行时生成 lambda 表达式的示例。文章中的这些行显示了如何生成 lambda 表达式:

var parameterExpression = Expression.Parameter(typeof(TEntity), "x");
var memberExpression = Expression.PropertyOrField(parameterExpression, prop.Name);
var memberExpressionConversion = Expression.Convert(memberExpression, typeof(object));
var lambda = Expression.Lambda<Func<TEntity, object>>(memberExpressionConversion, parameterExpression);

【讨论】:

    【解决方案2】:

    既然您已经在 cmets 中声明了您的意图,我相信接受的答案 here 就是您正在寻找的。即使它没有完全符合您的要求,这些行也可以延续:

    // TODO: Get 'type' from the property you want.
    Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
    LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
    

    您可以返回LambdaExpression,或者只使用该答案中的扩展方法,使用DynamicLinq。我猜这个故事的寓意(通常是这样)是它可能已经完成了:)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多