使用反射选择正确的泛型方法
在通过反射使用泛型方法时,当存在多个泛型重载时,选择正确的重载可能具有挑战性。当方法名称不明确时,例如 System.Linq.Queryable 类中的“Where”方法,就会出现此问题。
无需依赖假设或检查方法名称,有一种利用委托选择正确泛型重载的编译时安全方法。
静态方法
考虑以下具有多个泛型重载的静态方法:
<code class="language-csharp">public static void DoSomething<TModel>(TModel model) public static void DoSomething<TViewModel, TModel>(TViewModel viewModel, TModel model)</code>
要选择第一个重载(void 返回类型,一个泛型参数),请创建一个与其签名匹配的操作委托:
<code class="language-csharp">var method = new Action<object>(MyClass.DoSomething<object>);</code>
对于第二个重载(void 返回类型,两个泛型参数),请使用具有两个对象参数的操作委托:
<code class="language-csharp">var method = new Action<object, object>(MyClass.DoSomething<object, object>);</code>
此方法根据委托的泛型计数和参数计数选择正确的重载。
要获取 MethodInfo 对象,请使用委托的 Method 属性并调用 MakeGenericMethod():
<code class="language-csharp">var methodInfo = method.Method.MakeGenericMethod(type1, type2);</code>
静态扩展方法
对于实例方法,请使用类似的方法选择方法,但在将类型传递给 MakeGenericMethod() 之前调用 GetGenericMethodDefinition():
<code class="language-csharp">var methodInfo = method.Method.GetGenericMethodDefinition().MakeGenericMethod(type1);</code>
解耦 MethodInfo 和参数类型
您可以通过调用 GetGenericMethodDefinition() 来获取泛型 MethodInfo 对象,从而将 MethodInfo 对象的选择与参数类型解耦:
<code class="language-csharp">var methodInfo = method.Method.GetGenericMethodDefinition();</code>
然后,在调用方法时将必要的类型传递给 MakeGenericMethod():
<code class="language-csharp">processCollection(methodInfo, type2); ... protected void processCollection(MethodInfo method, Type type2) { var type1 = typeof(MyDataClass); object output = method.MakeGenericMethod(type1, type2).Invoke(null, new object[] { collection }); }</code>
以上是如何在 C# 中使用反射安全地选择正确的泛型方法重载?的详细内容。更多信息请关注PHP中文网其他相关文章!