我想得到方法System.Linq.Queryable.OrderyBy
方法,但我不断提出空值.
var type = typeof(T); var propertyInfo = type.GetProperty(group.PropertyName); var propertyType = propertyInfo.PropertyType; var sorterType = typeof(Func<,>).MakeGenericType(type, propertyType); var expressionType = typeof(Expression<>).MakeGenericType(sorterType); var queryType = typeof(IQueryable); var orderBy = typeof(System.Linq.Queryable).GetMethod("OrderBy", new[] { queryType, expressionType }); /// is always null.
有没有人有任何见解?我宁愿不循环GetMethods
结果.
解决了(通过黑客攻击LINQ)!
我在研究同样的问题时看到了你的问题.在找不到好的解决方案之后,我有了查看LINQ表达式树的想法.这是我想出的:
public static MethodInfo GetOrderByMethod() { Func fakeKeySelector = element => default(TSortKey); Expression , IOrderedEnumerable >> lamda = list => list.OrderBy(fakeKeySelector); return (lamda.Body as MethodCallExpression).Method; } static void Main(string[] args) { List ints = new List () { 9, 10, 3 }; MethodInfo mi = GetOrderByMethod (); Func keySelector = i => i.ToString(); IEnumerable sortedList = mi.Invoke(null, new object[] { ints, keySelector } ) as IEnumerable ; foreach (int i in sortedList) { Console.WriteLine(i); } }
输出:10 3 9
编辑:如果你在编译时不知道类型,这里是如何获取方法:
public static MethodInfo GetOrderByMethod(Type elementType, Type sortKeyType) { MethodInfo mi = typeof(Program).GetMethod("GetOrderByMethod", Type.EmptyTypes); var getOrderByMethod = mi.MakeGenericMethod(new Type[] { elementType, sortKeyType }); return getOrderByMethod.Invoke(null, new object[] { }) as MethodInfo; }
一定要用typeof(WhateverClassYouDeclareTheseMethodsIn)替换typeof(Program).
作为扩展方法的解决方案的变体:
public static class TypeExtensions { private static readonly Func> ParameterTypeProjection = method => method.GetParameters() .Select(p => p.ParameterType.GetGenericTypeDefinition()); public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes) { return (from method in type.GetMethods() where method.Name == name where parameterTypes.SequenceEqual(ParameterTypeProjection(method)) select method).SingleOrDefault(); } }
我认为以下扩展方法可以解决该问题:
public static MethodInfo GetGenericMethod( this Type type, string name, Type[] generic_type_args, Type[] param_types, bool complain = true) { foreach (MethodInfo m in type.GetMethods()) if (m.Name == name) { ParameterInfo[] pa = m.GetParameters(); if (pa.Length == param_types.Length) { MethodInfo c = m.MakeGenericMethod(generic_type_args); if (c.GetParameters().Select(p => p.ParameterType).SequenceEqual(param_types)) return c; } } if (complain) throw new Exception("Could not find a method matching the signature " + type + "." + name + "<" + String.Join(", ", generic_type_args.AsEnumerable()) + ">" + "(" + String.Join(", ", param_types.AsEnumerable()) + ")."); return null; }
该调用将类似于(仅更改原始代码的最后一行):
var type = typeof(T); var propertyInfo = type.GetProperty(group.PropertyName); var propertyType = propertyInfo.PropertyType; var sorterType = typeof(Func<,>).MakeGenericType(type, propertyType); var expressionType = typeof(Expression<>).MakeGenericType(sorterType); var queryType = typeof(IQueryable); var orderBy = typeof(Queryable).GetGenericMethod("OrderBy", new Type[] { type, propertyType }, new[] { queryType, expressionType });
与其他解决方案的不同之处在于:生成的方法与参数类型完全匹配,而不仅仅是它们的通用基本类型。