如何用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)
或其他一些。