How to call a generic extension method with reflection?

此生再无相见时 提交于 2019-11-28 01:51:50

The extension method isn't attached to the type Form, it's attached to the type MyClass, so grab it off that type:

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

In case you have an extension method like

public static class StringExtensions
{
    public static bool IsValidType<T>(this string value);
}

you can invoke it (e. g. in tests) like so:

public class StringExtensionTests
{
    [Theory]
    [InlineData("Text", typeof(string), true)]
    [InlineData("", typeof(string), true)]
    [InlineData("Text", typeof(int), false)]
    [InlineData("128", typeof(int), true)]
    [InlineData("0", typeof(int), true)]
    public void ShouldCheckIsValidType(string value, Type type, bool expectedResult)
    {
        var methodInfo = 
            typeof(StringExtensions).GetMethod(nameof(StringExtensions.IsValidType),
            new[] { typeof(string) });
        var genericMethod = methodInfo.MakeGenericMethod(type);
        var result = genericMethod.Invoke(null, new[] { value });
        result.Should().Be(expectedResult);
    }
}

Building off of @Mike Perrenoud's answer, the generic method I needed to invoke was not constrained to the same type as the class of the extension method (i.e. T is not of type Form).

Given the extension method:

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

I used the following code to execute the method:

private IEnumerable<string> 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;
        }
    }
}

where the types defined in _trackChangesOnTables are only known at runtime. By using the nameof operator, this protects against exceptions at runtime if the method or class is ever removed during refactoring.

You are passing in string as the generic parameter for your method..

But your constraints say that T needs to inherit from Form (which String does not).

I am assuming you wanted to write typeof(MyForm) or some such there instead.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!