如何用reflection调用generics扩展方法?

我写了扩展方法GenericExtension 。 现在我想调用扩展方法Extension 。 但methodInfo的值始终为null。

 public static class MyClass { public static void GenericExtension(this Form a, string b) where T : Form { // code... } public static void Extension(this Form a, string b, Type c) { MethodInfo methodInfo = typeof(Form).GetMethod("GenericExtension", new[] { typeof(string) }); MethodInfo methodInfoGeneric = methodInfo.MakeGenericMethod(new[] { c }); methodInfoGeneric.Invoke(a, new object[] { a, b }); } private static void Main(string[] args) { new Form().Extension("", typeof (int)); } } 

怎么了?

扩展方法没有附加到Form类型,它附加到MyClass类型,所以抓住它的类型:

 MethodInfo methodInfo = typeof(MyClass).GetMethod("GenericExtension", new[] { typeof(Form), typeof(string) }); 

基于@Mike Perrenoud的答案,我需要调用的generics方法不限于与扩展方法的类相同的类型(即T不是Form类型)。

鉴于扩展方法:

 public static class SqlExpressionExtensions { public static string Table(this IOrmLiteDialectProvider dialect) } 

我使用以下代码来执行该方法:

 private IEnumerable GetTrackedTableNames(IOrmLiteDialectProvider dialectProvider) { var method = typeof(SqlExpressionExtensions).GetMethod(nameof(SqlExpressionExtensions.Table), new[] { typeof(IOrmLiteDialectProvider) }); if (method == null) { throw new MissingMethodException(nameof(SqlExpressionExtensions), nameof(SqlExpressionExtensions.Table)); } foreach (var table in _trackChangesOnTables) { if (method.MakeGenericMethod(table).Invoke(null, new object[] { dialectProvider }) is string tableName) { yield return tableName; } } } 

其中_trackChangesOnTables中定义的类型仅在运行时已知。 通过使用nameof运算符,如果在重构期间删除了方法或类,则可以在运行时防止exception。

您将传入string作为方法的generics参数。

但是你的约束说T需要从Forminheritance(String不能)。

我假设你想写typeof(MyForm)或其他一些。