【问题标题】:Get OrderBy method using reflection使用反射获取 OrderBy 方法
【发布时间】:2015-04-01 09:11:56
【问题描述】:

我想为我的项目实现通用寻呼机和过滤视图模型,但我一直坚持使用反射获取 OrderBy 方法。这是我尝试过的,但不断收到null for methodInfo。似乎我将错误的 Type[] 参数传递给 GetMethod() 方法,但我无法正确处理。

    protected virtual Expression<Func<T, IComparable>> GetOrderByExpression()
    {
        var type = typeof(T);
        var property = type.GetProperty("DataSetName");
        var parameter = Expression.Parameter(type, "x");
        var propertyAccess = Expression.MakeMemberAccess(parameter, property);
        var orderByExp = Expression.Lambda(propertyAccess, parameter);
        var methodInfo = typeof(Enumerable).GetMethod("OrderBy", new Type[] { orderByExp.Body.Type });
        var predicateBody = Expression.Call(propertyAccess, methodInfo, orderByExp);
        var expression = Expression.Lambda<Func<T, IComparable>>(predicateBody, parameter);

        return expression;
    }

【问题讨论】:

  • 由于OrderBy 是一种扩展方法,我不确定它是否会存在于该上下文中。
  • This question, and answer 似乎有适当的信息来解决您的问题。
  • 我会试试的。谢谢。

标签: c# asp.net-mvc reflection expression-trees


【解决方案1】:

那么Enumerable.OrderBy扩展方法是一个静态方法,所以你必须使用GetMethod的重载,你可以指定BindingFlagsBindingFlags.Static | BindingFlags.Public而不是默认的BindingFlags.Instance | BindingFlags.Public)。

您还必须为该方法指定两个参数 - 从语法上看,它看起来只有一个参数,但因为它是一种扩展方法,所以您必须指定第二个参数。

这是你想通过反射得到的方法:

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
  this IEnumerable<TSource> source,
  Func<TSource, TKey> keySelector
)

你需要两种参数类型:

var sourceType = typeof(IEnumerable<>).MakeGenericType(type);
var keySelectorType = orderByExp.Compile().GetType();

似乎只有通过搜索才能获得具有泛型参数的方法的特定重载。幸运的是,Enumerable.OrderBy 只有两个重载,而您想要的一个是带有两个参数的重载:

var genericMethodInfo = typeof(Enumerable)
  .GetMethods(BindingFlags.Static | BindingFlags.Public)
  .First(mi => mi.Name == "OrderBy" && mi.GetParameters().Length == 2);
var methodInfo = genericMethodInfo.MakeGenericMethod(sourceType, keySelectorType);

这将返回所需的MethodInfo,但是您必须修改剩余的两行代码,因为此方法是静态方法,您必须在Expression.Call 中指定一个空实例。

【讨论】:

  • 感谢您提供的信息。我能够获得所需的“OrderBy”方法。
猜你喜欢
  • 2011-07-25
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
相关资源
最近更新 更多