无法从抽象<通用>转换为具体:抽象<具体:通用>
本文关键字:通用 抽象 具体 转换 | 更新日期: 2023-09-27 18:37:24
假设我有以下接口:
public interface IMessageProcessor<T> where T: BaseMessage {
void Process(T msg);
}
我有一个实现此接口的抽象类:
public abstract class AMessageProcessor<T> : IMessageProcessor<T> where T : BaseMessage {
protected Controller Controller { get; private set; }
public AMessageProcessor(Controller controller) {
Controller = controller;
}
public abstract void Process(T msg);
}
然后我有一条消息:
public class RRMessage : BaseMessage {
...
}
然后我有一个实现:
public class RRMessageProcessor : AMessageProcessor<RRMessage> {
public RRMessageProcessor(Controller controller) : base(controller) {}
public override void Process(RRMessage msg) {
//do something here
}
}
现在在另一个类中,我想为不同的消息列出这些处理器:
public readonly List<AMessageProcessor<BaseMessage>> AvailableMessageProcessors;
public MessageProcessingStrategy(Controller controller) {
AvailableMessageProcessors = new List<AMessageProcessor<BaseMessage>>();
/* ----- ERROR HAPPENS AT THIS LINE ------ */
AvailableMessageProcessors.Add(new RRMessageProcessor(controller));
}
我收到此错误:
错误 CS1503 参数 1: 无法从"RRMessageProcessor" 转换为 'AMessageProcessor
'
似乎转换应该有效...为什么它不能转换?我怎样才能让它工作?
我在另一个答案(已删除)中遇到了关于参数协变类型的问题,但这样的方法可能会解决您的问题:
-
定义一个
BaseMessageProcessor
类(可以是AMessageProcessor
),如下所示:public abstract class BaseMessageProcessor { protected Controller Controller { get; private set; } public BaseMessageProcessor(Controller controller) { Controller = controller; } public void Process<T>(T msg) where T : BaseMessage { if (this is IMessageProcessor<T>) (this as IMessageProcessor<T>).Process(msg); throw new NotSupportedException(); } }
-
定义接口
IMessageProcessorOf<T>
:public interface IMessageProcessor<T> where T : BaseMessage { void Process(T msg); }
-
定义继承
BaseMessageProcessor
和实现(显式)IMessageProcessorOf<T>
的具体处理器:public class RRMessageProcessor : BaseMessageProcessor, IMessageProcessorOf<RRMessage> { public RRMessageProcessor(Controller controller) : base(controller) { } void IMessageProcessor<RRMessage>.Process(RRMessage msg) { ... } }
此解决方案允许您使用AvailableMessageProcessors
:
public List<BaseMessageProcessor> AvailableMessageProcessors;
...
AvailableMessageProcessors = new List<BaseMessageProcessor>();
AvailableMessageProcessors.Add(new RRMessageProcessor(controller));
因此,如果您有 2 种消息类型,例如 RRMessage
和 SSMessage
,您可以定义一个MultiMessageProcessor
:
public class MultiMessageProcessor : BaseMessageProcessor, IMessageProcessorOf<RRMessage>, IMessageProcessorOf<SSMessage>
{
public MultiMessageProcessor(Controller controller) : base(controller) { }
void IMessageProcessorOf<RRMessage>.Process(RRMessage msg)
{
...
}
void IMessageProcessorOf<SSMessage>.Process(SSMessage msg)
{
...
}
}
对Process()
方法的调用将通过BaseMessageProcessor.Process<>
:
multiProcessor.Process(new RRMessage());
multiProcessor.Process(new SSMessage());
或者只是使用RRMessageProcessor
并使用与以前相同的想法定义SSMessageProcessor
。
这不是最干净/最漂亮的方法,但它似乎有效。以下是我在AMessageProcessor中更改的内容:
public abstract class AMessageProcessor : IMessageProcessor<BaseMessage>
protected Controller Controller { get; private set; }
public AMessageProcessor(Controller controller) {
Controller = controller;
}
/* ----- REALLY DON'T WANT TO OVERRIDE THIS METHOD EVERYWHERE --- */
public abstract void Process(BaseMessage msg);
}
然后将 RRMessageProcessor 更改为:
public class RRMessageProcessor : AMessageProcessor, IMessageProcessor<RRMessage> {
public RRMessageProcessor(Controller controller) : base(controller) {}
/* ----- REALLY DON'T WANT TO OVERRIDE THIS METHOD LIKE THIS EVERYWHERE --- */
public override void Process(BaseMessage msg) {
Process(msg as RRMessage);
}
public void Process(RRMessage msg) {
//do something here
}
}
在泛型类型上,需要将类型定义为协变。请参阅 https://msdn.microsoft.com/en-us/library/dd997386.aspx
这应该有效
public interface IMessageProcessor<in T> where T : BaseMessage
{
void Process(T msg);
}
您可以通过重新定义轻松解决问题
public readonly List<AMessageProcessor<BaseMessage>> AvailableMessageProcessors;
到
public readonly List<RRMessageProcessor> AvailableMessageProcessors;
因此,您没有转换问题,并且使用的是自定义对象
希望对您有所帮助!