如何用反射调用泛型扩展方法?

时间:2013-04-10 13:19:42

标签: c# generics extension-methods methodinfo

我写了扩展方法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));
    }
}

怎么了?

4 个答案:

答案 0 :(得分:18)

扩展方法未附加到Form类型,它附加到MyClass类型,因此请抓取该类型:

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

答案 1 :(得分:0)

以@Mike Perrenoud的回答为基础,我需要调用的通用方法没有被限制为与扩展方法的类相同的类型(即wins, players_count 1, 1 2, 3 的类型不是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运算符,如果在重构期间删除了方法或类,这可以防止运行时发生异常。

答案 2 :(得分:0)

如果您有扩展方法,例如

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

答案 3 :(得分:-2)

您传入的字符串是您方法的通用参数..

但是你的约束说T需要从Form继承(String没有)。

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