2016-11-21 51 views
3

有效我有以下兩種實體框架的包括如下的方法:獲取方法的MethodInfo的 - 該操作僅在泛型類型

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

我得到的錯誤:

This operation is only valid on generic types

什麼時我錯過了?

+0

'string navigationPropertyPath'是通用的嗎? – CodeCaster

+0

不,這只是一個字符串...我在上面添加了方法簽名。 –

+0

'ParameterType.GetGenericTypeDefinition()'如何返回'typeof(String)'? –

回答

4

好的,讓我們分開。首先你想得到方法的所有過載:

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

這產生了第二個重載,符合市場預期,並沒有抱怨你試圖從第二個參數上typeof(string)調用GetGenericTypeDefinition

+0

首先,我認爲你的意思是IsGenericParameter而不是IsGenericType。其次,您沒有返回MethodInfos,而是返回類型。所以include2是一個類型列表。最後,我終於沒有收到物品。任何想法爲什麼? –

+0

@MiguelMoura不,我的意思是'IsGenericType',而不是'IsGenericParameter'。我自己測試了它,它的工作原理,請參閱:https://gist.github.com/masaeedu/7150ee92becdad4e514dfa160da460ad。其次,我在兩個片段中都返回了一個IEnumerable ',而不是'IEnumerable '。我鼓勵你將代碼粘貼到你的IDE中。 –

+0

@MiguelMoura也許你對縮進感到困惑,但第二個片段實際上就是你的代碼,其中'Select'子句被修改爲具有三元表達式。 –

相關問題