2011-10-14 55 views
2

這可能聽起來很愚蠢,但我不能得到 Queryable.Join(...)。我想得到它,因爲How to use a Type variable in a generic method call (C#)我怎樣才能得到Queryable.Join的MethodInfo

它有2個可用的方法簽名,我想得到一個沒有IEqualityComparer,所以我需要在GetMethod指定Type[]

我寫的東西像

MethodInfo joinMethod = typeof(Queryable).GetMethod("Join", new Type[] { typeof(IEnumerable<>), typeof(Expression<Func<>>), typeof(Expression<Func<>>), typeof(Expression<Func<>>)}); 

,但它不工作。我無法在上面的泛型中指定類型,因爲它們從外部傳遞爲Type(這就是爲什麼我需要這種反射)。

誰能告訴我怎麼樣?謝謝!

+1

請記住'Queryable.Join'是一個擴展方法,所以方法的第一個參數是'this IQueryable '。另外,[this](http://stackoverflow.com/questions/269578/get-a-generic-method-without-using-getmethods)問題非常相似。 – vcsjones

+0

哦,是的!謝謝。我會看一看。 – uni

回答

5

使用泛型和反射可能有點乏味。你最好的選擇(保持簡單)就是使用GetMethods,並根據你的要求進行過濾。

//Overly simplified 
MethodInfo joinMethod = typeof(Queryable) 
      .GetMethods(BindingFlags.Static | BindingFlags.Public) 
      .Where(m => m.Name == "Join" && m.GetParameters().Length == 5) 
      .First(); 

鑑於此,MethodInfo此時不可調用。您需要使用joinMethod.MakeGenericMethod(/*type array*/)來製作它的通用版本。在你的情況下,你需要使用4種類型:TOuter,TInner,TKey,TResult。

var genericJoinMethod = joinMethod.MakeGenericMethod(new Type[]{your types here}); 

現在您可以像預期的那樣使用genericJoinMethod了。

據我所知,如果你不知道編譯時的類型,這是唯一的方法。

編輯

考慮您的意見,我認爲它應該是這個樣子:

MethodInfo joinMethod = typeof(Queryable) 
      .GetMethods(BindingFlags.Static | BindingFlags.Public) 
      .Where(m => m.Name == "Join" && m.GetParameters().Length == 5) 
      .First(); 
var genericJoinMethod = joinMethod.MakeGenericMethod(typeof(TType), typeof(TType), JoinKeyType, typeof(TType)); 
result = genericJoinMethod.Invoke(result, new object[] { result, items, OuterKeySelector, InnerKeySelector, ResultSelector }); 
+0

這真的簡化了事情!我在嘗試調用方法後出現了另一個錯誤,例如這種'joinMethod.MakeGenericMethod(typeof(TType),typeof(TType),JoinKeyType,typeof(TType)); \t \t \t \t結果= joinMethod.Invoke(結果,新的對象[] {結果,物品,OuterKeySelector,InnerKeySelector,ResultSelector});'是「後期綁定操作不能在類型或方法針對ContainsGenericParameters是真正執行的錯誤「.. 有任何想法嗎? – uni

+2

@uni - 確保在調用'Invoke'時使用'MakeGenericMethod'返回的新'MethodInfo'。 – vcsjones

+0

我想知道如果DLR中的某個地方已經不是所有這些,那麼C#部分必須有一些東西來解析來自特定調用站點的調用的MethodInfo。但它可能不會被曝光:( –

1

開始之前實現一些複雜的反射搜索與字符串和參數計數參與,爲什麼不你退後一步,讓編譯器做他更擅長的事情嗎?

​​

很明顯,你可以把任何你想在你的表達,只要頂層的東西是你的加入方法調用。類型都不重要。