2016-11-22 112 views
1

泛型方法與表達我有應該從表中返回的最後一條記錄的一般方法:呼叫通過反射

public T FindLast<TKey>(Expression<Func<T,TKey>> specification = null) 
{ 
    return specification == null 
     ? Set().LastOrDefault() 
     : Set().OrderBy(specification).LastOrDefault(); 
} 

我需要通過反射

var methodCreateReadRepositoryAttr = (entityMetadata.GetEntityAttributeType() != null) ? 
typeof(IRepositoryFactory).GetMethod("CreateReadRepository").MakeGenericMethod(entityMetadata.GetEntityAttributeType()) : null; 

var methodEntityGet3 = attributeReadRepository.GetType().GetMethod("FindLast", new Type[] { typeof(Expression<Func<ArticleAttribute,int>>) }); 

但在調試methodEntityGet3叫它一片空白。我做錯了什麼?

+0

你可以調用它沒有反映? –

回答

0

您需要打破你的方法調用兩個:

var methodEntityGet3 = attributeReadRepository.GetType().GetMethod("FindLast"); 
var closedGenericMethod = methodEntity3.MakeGenericMethod(new Type[] { typeof(Expression<Func<ArticleAttribute,int>>) }; 
1

問題是您正在請求一種封閉類型的方法,同時方法FindLast是通用類型,並且具有開放類型,即參數類型爲Expression<Func<T, TKey>>,而不是您提供的類型。反思系統不會去創建最適合的通用方法,因爲這可能取決於語言中的規則。您可能會將參數轉換爲dynamic,但我不完全確定這一點。

此外,有沒有簡單的方法來獲取類型參數TTKey,所以我建議你搜索方法只能用它的名字,然後明確創建下面的泛型方法,像你這樣的方法同上。

編輯:實際上,dynamic解決方案實際上工作,並且可能比任何反射調用可讀性要好得多。下面的代碼編譯和輸出可以預期的:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var foo = new Foo<string>(); 
     Expression<Func<string, int>> arg = s => s.Length; 
     CallFindLast(foo, arg); 
     Console.Read(); 
    } 

    private static void CallFindLast(Foo<string> foo, object arg) 
    { 
     var dynamicArg = (dynamic)arg; 
     foo.FindLast(dynamicArg); 
    } 

    private class Foo<T> 
    { 
     public T FindLast<TKey>(Expression<Func<T, TKey>> specification = null) 
     { 
      Console.WriteLine($"T: {typeof(T).Name}, TKey: {typeof(TKey).Name}"); 
      return default(T); 
     } 
    } 
}