我正在尝试使用反射自动注册请求处理类。
这是手动添加处理程序以执行特定请求的示例。
// 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/