获取方法的MethodInfo - 此操作仅对泛型类型

时间:2016-11-21 16:29:22

标签: c# reflection

我有以下两个Entity Framework的Include方法:

public static IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
    [NotNullAttribute] this IQueryable<TEntity> source, 
    [NotNullAttribute] Expression<Func<TEntity, TProperty>> navigationPropertyPath) 
    where TEntity : class;

public static IQueryable<TEntity> Include<TEntity>(
    [NotNullAttribute] this IQueryable<TEntity> source,
    [NotNullAttribute][NotParameterized] string navigationPropertyPath) 
    where TEntity : class;

我需要为这两种方法获取MethodInfo。对于我使用的第一个:

  MethodInfo include1 = typeof(EntityFrameworkQueryableExtensions)
    .GetMethods().First(x => x.Name == "Include" && x.GetParameters()
    .Select(y => y.ParameterType.GetGenericTypeDefinition())
    .SequenceEqual(new[] { typeof(IQueryable<>), typeof(Expression<>) }));

这有效但当我尝试使用以下内容获取第二个时:

  MethodInfo include2 = typeof(EntityFrameworkQueryableExtensions)
    .GetMethods().First(x => x.Name == "Include" && x.GetParameters()
    .Select(y => y.ParameterType.GetGenericTypeDefinition())
    .SequenceEqual(new[] { typeof(IQueryable<>), typeof(String) }));

我收到错误:

  

此操作仅对通用类型

有效

我错过了什么?

1 个答案:

答案 0 :(得分:5)

好的,让我们分开吧。首先,您希望获得该方法的所有重载:

var overloads = typeof(EntityFrameworkQueryableExtensions)
    .GetMethods()
    .Where(method => method.Name == "Include");

然后,您希望将参数类型与特定序列匹配,以便您可以选择适当的重载。代码的问题在于,假设所有参数都是通用类型,则情况并非如此。您可以使用三元子句来区分泛型和非泛型参数类型:

var include2 =  overloads.Where(method => method
    .GetParameters()
    .Select(param => param.ParameterType.IsGenericType ? param.ParameterType.GetGenericTypeDefinition() : param.ParameterType)
    .SequenceEqual(new[] { typeof(IQueryable<>), typeof(string) }));

这会产生第二次重载,如预期的那样,并且不会抱怨您尝试从第二个参数调用GetGenericTypeDefinition上的typeof(string)