如何调用与反思的通用扩展方法?(How to call a generic extension me

2019-08-21 08:12发布

我写的扩展方法GenericExtension 。 现在我想调用扩展方法Extension 。 但是价值methodInfo总是空。

public static class MyClass
{
    public static void GenericExtension<T>(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));
    }
}

怎么了?

Answer 1:

该扩展方法没有连接到类型Form ,它附着在类型MyClass ,因此,抓住它关闭该类型:

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


Answer 2:

建立关@Mike Perrenoud的回答,我需要调用通用的方法并没有限制在同类型作为类的扩展方法(即T不是类型的Form )。

鉴于扩展方法:

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

我用下面的代码以执行该方法:

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;
        }
    }
}

其中定义的类型_trackChangesOnTables仅在运行时是已知的。 通过使用nameof操作,这样可以防止异常运行时,如果重构过程中曾经删除的方法或类。



Answer 3:

如果你有一个扩展方法一样

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

你可以调用它(例如,在测试),如下所示:

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);
    }
}


Answer 4:

您传递字符串作为你的方法泛型参数..

但你的约束说,T需要从表继承(其中字符串不)。

我假设你想写typeof(MyForm)或一些这样的事吧。



文章来源: How to call a generic extension method with reflection?