透過反射選擇合適的泛型方法可能具有挑戰性,尤其是在方法存在多個泛型重載時。本文探討了一種編譯安全性的有效方法來選擇正確的泛型方法,而無需依賴字串或運行時搜尋。
結合使用 lambda 表達式或委託和 MethodInfo.MakeGenericMethod
方法,可以在編譯時選擇特定的泛型重載。例如,如果您有以下泛型方法:
<code>public static void DoSomething<TModel>(TModel model)</code>
您可以建立一個委託來匹配其泛型計數和參數計數:
<code>var method = new Action<object>(MyClass.DoSomething<object>);</code>
透過 object
取代泛型類型,您可以選擇正確的重載,而無需求助於運行時管道或有風險的字串操作。
對於靜態方法(例如 System.Linq.Queryable
類別中的方法),您可以使用類似的方法。例如,要選擇一個採用 IQueryable<TModel>
和 Expression<Func<TModel, bool>>
的 Where
方法,您可以執行以下操作:
<code>var method = new Func<IQueryable<object>, Expression<Func<object, bool>>, IQueryable<object>>(Queryable.Where<object>);</code>
要選擇實例方法,您可以遵循類似的模式,但在呼叫 MakeGenericMethod
之前使用 GetGenericMethodDefinition
取得泛型 MethodInfo
。
MethodInfo
和參數型別您可以使用 GetGenericMethodDefinition
將 MethodInfo
的選擇與泛型類型的賦值解耦,並將 MethodInfo
傳遞給另一個知道要實例化類型的並使用該類型調用該方法的方法。
為了說明這個方法,考慮一個具有多個重載的泛型方法 CopyList
的類別。以下程式碼顯示如何使用上述技術選擇正確的重載:
<code>var listTo = ReflectionHelper.GetIEnumerableType(fromValue.GetType()); var fn = new Func<IEnumerable<object>, Func<PropertyInfo, bool>, Dictionary<Type, Type>, IEnumerable<object>>(ModelTransform.CopyList<object>); var copyListMethod = fn.GetMethodInfo().GetGenericMethodDefinition().MakeGenericMethod(listTo); copyListMethod.Invoke(null, new object[] { fromValue, whereProps, typeMap });</code>
透過利用 lambda 表達式和委託的功能,您可以透過反射優雅地選擇正確的泛型方法,確保編譯時安全並避免基於字串或運行時搜尋的陷阱。
以上是如何使用反射安全地選擇正確的泛型方法重載?的詳細內容。更多資訊請關注PHP中文網其他相關文章!