在 .NET 中,當存在多個泛型方法重載時,嘗試使用反射來選擇正確的版本可能會帶來挑戰。例如,System.Linq.Queryable
類別中的靜態方法具有 Where
方法的兩個定義:
<code class="language-c#">static IQueryable<T> Where(this IQueryable<T> source, Expression<Func<T, bool>> predicate) static IQueryable<T> Where(this IQueryable<T> source, Expression<Func<T, bool>> predicate)</code>
反射中的 GetMethod
方法不足以完成此任務,因為它無法區分這些重載。
為了選擇正確的泛型方法,我們可以採用一種涉及創建參數化委託的技術。透過建立一個與所需重載的泛型計數和參數計數相符的 Action
或 Func
委託,我們可以在編譯時選擇該方法:
範例 1: 選擇採用一個泛型型別和單一參數的 Where
方法:
<code class="language-c#">var method = new Action<object>(MyClass.DoSomething<object>);</code>
範例 2: 選擇採用兩個泛型類型和兩個參數的 Where
方法:
<code class="language-c#">var method = new Action<object, object>(MyClass.DoSomething<object, object>);</code>
這種方法允許我們獲得所需的方法,而無需依賴有風險的字串或運行時搜尋。
如果您需要 MethodInfo
對象,則可以在建立委託後取得它:
<code class="language-c#">var methodInfo = method.Method.MakeGenericMethod(type1, type2);</code>
靜態擴充方法需要稍微複雜一點的方法,但相同的原理適用:
<code class="language-c#">var method = new Func<IQueryable<object>, Expression<Func<object, bool>>, IQueryable<object>>(Queryable.Where<object>); var methodInfo = method.Method.MakeGenericMethod(modelType);</code>
有時,可能需要解耦 MethodInfo
物件和參數類型:
<code class="language-c#">var methodInfo = method.Method.GetGenericMethodDefinition(); methodInfo.MakeGenericMethod(type1, type2).Invoke(null, new object[] { collection });</code>
此技術可讓您執行複雜的操作,例如從類別中選擇實例方法並將其公開以用於不同類型。
透過使用參數化委託,我們可以繞過 GetMethod
的限制,並在編譯時選擇正確的泛型方法。這種方法確保類型安全並避免不必要的動態查找。
以上是如何使用反射在 .NET 中選擇正確的重載通用方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!