2016-01-28 46 views
2

我想知道如何使用反射在C#中調用下面的方法:如何在C#中使用通用參數調用通用方法?

public static List<T> GetAllWithChildren<T> 
    (this SQLiteConnection conn, Expression<Func<T, bool>> filter = null, bool recursive = false) 
    where T 
    #if USING_MVVMCROSS: new() #else : class #endif 
    { 
    } 

我當前的代碼是:

MethodInfo methodInfo = typeof(ReadOperations).GetMethod("GetWithChildren", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); 
Type predicateType = predicate.GetType(); 
MethodInfo genericMethod = methodInfo.MakeGenericMethod(predicateType); 
Type[] genericArgumentsType = genericMethod.GetGenericArguments(); 
Debug.WriteLine("Arguments Number:" + genericArgumentsType.Count()); 
int count = 0; 
foreach (Type ga in genericArgumentsType) 
{ 
    Console.WriteLine(count++ + " " + ga.GetType()); 
} 
Object[] genericArguments = { conn, predicate, true }; 
genericMethod.Invoke(conn, genericArguments); 

返回參數的個數爲1 ...,它是錯了,但我不知道爲什麼系統返回給我這個數字。

invoke方法失敗,參數數量錯誤。

任何幫助將受到歡迎!

+0

_Generic arguments_的數量是一個('T')。 _parameters_的數量是3('SQLiteConnection conn','Expression > filter'和'bool recursive')。您可以通過調用'GetParameters'來獲取參數。 –

+0

還要注意'predicateType'將會是'Expression >'這不是在調用'MakeGenericMethod'時使用的正確類型。 –

回答

1

你用GetWithChildren而不是GetAllWithChildren調用它。

1

您正在使用Predicate的泛型參數來使該方法具有通用性。這意味着:

Expression<Func<T, bool>>的一般參數將是Func<T, bool>這不是您正在尋找標記方法的實際類型。更新以下行:

Type predicateType = predicate.GetType(); 
MethodInfo genericMethod = methodInfo.MakeGenericMethod(predicateType); 

Type parameterType = predicate.Parameters[0].Type; 
MethodInfo genericMethod = methodInfo.MakeGenericMethod(parameterType); 

這會給你的T類型從Func<T,bool>。現在它應該按預期工作。

以上更改基於假設您謂詞類型爲Expression<Func<T, bool>>。如果謂詞爲Func<T, bool>那麼參數類型,可以取象下面這樣:

Type parameterType = predicate1.GetType().GetGenericArguments()[0]; 
+1

任何時候我看到'MakeGenericMethod'所有我看到的都是HULK SMASH。微軟需要解決這個瘋狂的API –

0

您的通用方法是擴展方法....更改下面的代碼,然後再試一次

MethodInfo methodInfo = typeof(**SQLiteConnection**).GetMethod("GetAllWithChildren", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);