c# - 无法使用反射将方法组转换为非委托类型
问题描述
我正在尝试使用反射自动注册请求处理类。
这是手动添加处理程序以执行特定请求的示例。
// generic manual method of registration
server.RegisterHandler<GetData>(base.ExecuteMessage);
这是使用反射进行注册的尝试。调用方法将不接受 'ExecuteMessage' 方法,出现错误“错误 CS0428 无法将方法组 'ExecuteMessage' 转换为非委托类型 'object'。您是否打算调用该方法?”。
// 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)
{
}
}
}
解决方案
“无法转换方法组...”的原因是因为编译器不知道要将其转换为的委托的类型。
您还需要使用反射调用 Func 构造函数。这也很复杂,因为它IMessage
也是通用的。
您还需要重新定义ExecuteMessage
为泛型以匹配委托类型:
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 });
}
推荐阅读
- react-native - React Native RNDateTimePicker:无法选择日期
- python - 删除 txt 文件中特定字符之间的所有内容
- python - 为什么gdb和python中的十六进制地址添加不一样
- python - 为什么我的极小极大算法没有做出完美的一步 - 1D Chess?
- android - 如何使用特定片段开始活动
- python - Python遍历多个列表,每次从索引0开始
- c++ - 使用默认的 windows pdf opener 在 C++ 中打开嵌入的 pdf 资源文件
- ffmpeg - 将 16 位灰度 PNG 转换为 HEVC/x265
- angular - Angular / Type脚本如何从json对象打印值
- google-pagespeed - html缩小不再是一个因素?