首页 > 解决方案 > 使用泛型类型执行类的反射

问题描述

在使用反射(查找接口实现)找到它之后,我想在使用泛型类型的类上动态执行一个方法。

下面是我被卡住的一个例子。非常感谢您的帮助。

设置

public interface IActionRequired<T> where T : class {
    void DoThis(T[] receivedObjects);
}

public class BookDetails {
    public int BookId { get; set; }

    public string BookName { get; set; }
}

public class LibraryBookReturned : IActionRequired<BookDetails>
{
    public void DoThis(BookDetails[] receivedObjects)
    {
        foreach(var book in receivedObjects)
            System.Console.WriteLine(book.BookName);
    }
}

使用反射的示例尝试

下面,我只是使用第一个实现,但在现实世界中,我将使用命名约定来定位正确的实现。

        var assembly = Assembly.GetCallingAssembly();
        var listOfImplementations = 
                GetAllTypesImplementingOpenGenericType(typeof(IActionRequired<>), assembly);
        var implementation = listOfImplementations.FirstOrDefault();
        var implementationUsesInterface = implementation.GetInterfaces() [0];
        var interfaceUsesType = implementationUsesInterface.GetGenericArguments() [0];

我知道以下内容将不起作用(我收到一条错误消息说 interfaceUsesType 是变量而不是类型),但它表明了我想要做的事情:

        var instance = 
            assembly.CreateInstance(implementation.FullName) as IActionRequired<interfaceUsesType>;
        var results = this.CheckForMessages<interfaceUsesType>();
        instance.DoThis(results);

标签: c#.net-core

解决方案


您将不得不发出泛型方法的运行时类型特定版本。看看那个MethodInfo.MakeGenericMethod

MakeGenericMethod 方法允许您编写将特定类型分配给泛型方法定义的类型参数的代码,从而创建表示特定构造方法的 MethodInfo 对象。如果此 MethodInfo 对象的 ContainsGenericParameters 属性返回 true,则可以使用它来调用方法或创建委托来调用方法。

简而言之(伪)代码:

this.GetType()
    .GetMethod("CheckForMessages")
    .MakeGenericMethod(interfaceUsesType)
    .Invoke(this, null);

您也可以在此处阅读:如何:使用运行时类型调用泛型方法


推荐阅读