C# 作为泛型参数传递对象时如何使用对象的基础类型

C# 作为泛型参数传递对象时如何使用对象的基础类型,c#,generics,delegates,C#,Generics,Delegates,我有一个MessageBroker服务,它以代码的形式发送来自不同组件的消息。它依赖于定义哪些方法处理哪些消息的属性 这项服务的关键在于HandleMessage方法: private void HandleMessage<TMessage, TSender>(TMessage message, TSender sender = null) where TMessage : Message where TSender : class { var messageType = m

我有一个MessageBroker服务,它以代码的形式发送来自不同组件的消息。它依赖于定义哪些方法处理哪些消息的属性

这项服务的关键在于
HandleMessage
方法:

private void HandleMessage<TMessage, TSender>(TMessage message, TSender sender = null) where TMessage : Message where TSender : class
{
    var messageType = message.GetType();
    if (messageHandlers.TryGetValue(messageType, out List<Delegate> handlers))
    {
        foreach (var handler in handlers)
        {
            try
            {
                if (handler is Action<TSender, TMessage> h)
                    ThreadPool.QueueUserWorkItem(x => h.Invoke(sender, message));
                else
                {
                    ThreadPool.QueueUserWorkItem(x => handler.DynamicInvoke(sender, message));
                }
            }
            catch(Exception e)
            {
                log?.LogError($"Attempt to handle a message failed. {e.Message}");
            }
        }
    }
    else
    {
        log?.LogError(string.Format("No handler found for message of type {0}", messageType.FullName));
        throw new NoHandlersException(messageType.FullName);
    }
}
private void HandleMessage(TMessage message,TSender sender=null),其中TMessage:message其中TSender:class
{
var messageType=message.GetType();
if(messageHandlers.TryGetValue(messageType,out-List处理程序))
{
foreach(处理程序中的变量处理程序)
{
尝试
{
if(处理程序是动作h)
QueueUserWorkItem(x=>h.Invoke(发送方,消息));
其他的
{
ThreadPool.QueueUserWorkItem(x=>handler.DynamicInvoke(发送方,消息));
}
}
捕获(例外e)
{
log?.LogError($“尝试处理消息失败。{e.message}”);
}
}
}
其他的
{
log?.LogError(string.Format(“未找到类型为{0}”、messageType.FullName的消息的处理程序”);
抛出新的NoHandlersException(messageType.FullName);
}
}
对我来说很重要的一个特性是不必在处理程序方法本身中强制转换发送者或消息,因此当处理程序“注册”时,它将注册为
操作
,其中T1和2是处理程序接受的特定类型

在组件之间(进程中)发送消息时,一切都很好,因为消息的类型(通常)在编译时是已知的,因此它的类型可以是特定的(即不是所有消息继承自的基本
消息
类)

但是,我需要支持通过网络到达的消息。它们以序列化的方式到达,并在标头中使用类型代码。因此,在运行时之前无法知道将要到达的消息类型

简而言之,当消息通过网络到达时,
HandleMessage
方法中的
TMessage
是类型
message
,而不是反序列化的特定消息类型

这会导致模式匹配(
if(处理程序是操作h)
)失败,并强制我使用
DynamicInvoke


有什么方法可以“强制”将泛型类型作为消息的特定类型吗?

尝试通过泛型上的约束将TMessage设置为BrokeredMessage类型,然后使用:

var ct = brokeredMessage.ContentType;
Type bodyType = Type.GetType(ct, true);
以获取实际类型