c# - 无法通过反射将方法组转换为非委托(delegate)类型

标签 c# reflection

我正在尝试使用反射自动注册请求处理类。

这是手动添加处理程序以执行特定请求的示例。

// generic manual method of registration
server.RegisterHandler<GetData>(base.ExecuteMessage);

这是通过反射进行注册的尝试。调用方法不会接受“ExecuteMessage”方法,并出现错误“错误 CS0428 无法将方法组“ExecuteMessage”转换为非委托(delegate)类型“对象”。您打算调用该方法吗?”。

// registration with reflection
foreach (var type in serviceTypes)
{
    // registerHandlerMethod definition:    RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn)
    // ExecuteMessage definition:           object ExecuteMessage(IMessage message)

    registerHandlerMethod.MakeGenericMethod(type).Invoke(server, new object[] { base.ExecuteMessage });
}

是否可以以任何方式强制转换 ExecuteMessage 方法以使其正常工作?

编辑:添加了以下问题的示例

class Program
{
    static void Main(string[] args)
    {
        var server = new Server();

        // generic manual method of registration
        server.RegisterHandler<GetData>(ExecuteMessage);

        // registration with reflection
        var serviceTypes = new List<Type> { typeof(GetData) };
        var registerHandlerMethod = typeof(Server).GetMethod(nameof(Server.RegisterHandler));

        foreach (var type in serviceTypes)
        {
            registerHandlerMethod.MakeGenericMethod(type).Invoke(server, new object[] { ExecuteMessage });
        }
    }

    static object ExecuteMessage(IMessage message)
    {
        return null;
    }

    internal class GetData
    {

    }

    internal interface IMessage<T> : IMessage
    {

    }

    internal interface IMessage
    {

    }

    internal class Server
    {

        internal void RegisterHandler<T>(Func<IMessage<T>, object> processMessageFn)
        {
        }
    }
}

最佳答案

“无法转换方法组...”的原因是编译器不知道要将其转换为的委托(delegate)类型。

您还需要通过反射调用 Func 构造函数。由于 IMessage 也是通用的,这一事实使情况变得复杂。

您还需要将 ExecuteMessage 重新定义为泛型以匹配委托(delegate)类型:

static object ExecuteMessage<T>(IMessage<T> message)
{
    return null;
}

我认为您需要的代码如下:

var executeMethod = typeof(Program).GetMethod(nameof(ExecuteMessage), BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var type in serviceTypes)
{
    var messageType = typeof(IMessage<>).MakeGenericType(type);
    var funcType = typeof(Func<,>).MakeGenericType(messageType, typeof(object));
    var func = executeMethod.MakeGenericMethod(type).CreateDelegate(funcType, this);  // don't pass this for static methods
    registerHandlerMethod.MakeGenericMethod(type).Invoke(server, new object[] { func });
}

关于c# - 无法通过反射将方法组转换为非委托(delegate)类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65790821/

相关文章:

c# - PropertyDescriptor.SetValue 在 ModelBinder 中不起作用

C# 使用反射动态实例化

c# - 字符串后的正则表达式行

c# - axVLCPlugin(VideoLAN) 更快的状态到正常状态

c# - Unity - Raycast 对 child 不起作用

c# - 有没有办法在运行时将类文件加载到程序集?

Java:从 JAR 文件中的类文件中获取方法 stub 的简单方法?反射?

c# - 需要帮助找出返回类型

c# - 如何将 gi-normous 整数(字符串格式)转换为十六进制格式? (C#)

c# - 加载具有相关引用的程序集