在 .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中文网其他相关文章!