假设我有以下界面:
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:无法转换为&#39; RRMessageProcessor&#39;至 &#39;&AMessageProcessor LT; BaseMessage&GT;&#39;
似乎转换应该有效...为什么它无法转换?我怎样才能让它发挥作用?
答案 0 :(得分:1)
我的其他答案(删除)中有关于参数协变类型的问题,但这样的方法可以解决您的问题:
定义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
。
答案 1 :(得分:0)
这不是最干净/最漂亮的方式,但似乎有效。这是我在 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
}
}
答案 2 :(得分:0)
在您的通用类型上,您需要将类型定义为协变。见https://msdn.microsoft.com/en-us/library/dd997386.aspx
这应该有效
public interface IMessageProcessor<in T> where T : BaseMessage
{
void Process(T msg);
}
答案 3 :(得分:-1)
您可以通过重新定义
轻松解决问题 public readonly List<AMessageProcessor<BaseMessage>> AvailableMessageProcessors;
到
public readonly List<RRMessageProcessor> AvailableMessageProcessors;
因此,您不会遇到问题并且您正在使用自定义对象
希望能帮到你!