繁体   English   中英

如何创建从实现接口的基类派生的实例列表?

[英]How to create list of instances deriving from a base class that implements interface?

考虑以下接口和类声明。

public interface IMessage
{
    string Body { get; set; }
}
public abstract class MessageBase : IMessage
{
    public string Body { get; set; }
}
public class MessageA : MessageBase { }
public class MessageB : MessageBase { }
public class MessageC : MessageBase { }

public interface IMessageProcessor<T> where T : IMessage
{
    Action<T> ProcessorAction { get; set; }
}
public abstract class MessageProcessorBase<T> : IMessageProcessor<T> where T : MessageBase
{
    public Action<T> ProcessorAction { get; set; }
}
public class MessageAProcessor : MessageProcessorBase<MessageA> { }
public class MessageBProcessor : MessageProcessorBase<MessageB> { }
public class MessageCProcessor : MessageProcessorBase<MessageC> { }

现在,我想像这样声明处理器实例的列表,但无法弄清楚哪种通用类型将允许我将任何派生的处理器类型添加到列表中。

var processors = new List<???>();
processors.Add(new MessageAProcessor());
processors.Add(new MessageBProcessor());
processors.Add(new MessageCProcessor());

我努力了:

// compiles but throws InvalidCastException
var processors = new List<IMessageProcessor<IMessage>>();
processors.Add((IMessageProcessor<IMessage>)new MessageAProcessor());

// compiles but throws InvalidCastException
var processors = new List<IMessageProcessor<MessageBase>>();
processors.Add((IMessageProcessor<MessageBase>)new MessageAProcessor());

// won't compile
var processors = new List<MessageProcessorBase<MessageBase>>();
processors.Add((MessageProcessorBase<MessageBase>)new MessageAProcessor());

此列表的类型应该是什么? 我知道我一定会在这里遗漏一些明显的东西。 在这里的任何帮助将不胜感激。 谢谢!

您需要引入IMessageProcessor并从中继承所有处理器。 在列表中,您将必须使用此界面。

public interface IMessage {
    string Body { get; set; }
}

public abstract class MessageBase : IMessage {
    public string Body { get; set; }
}

public class MessageA : MessageBase {
}

public class MessageB : MessageBase {
}

public class MessageC : MessageBase {
}

public interface IMessageProcessor<T> where T : IMessage {
    Action<T> ProcessorAction { get; set; }
}

public abstract class MessageProcessorBase<T> : IMessageProcessor<T> where T : MessageBase {
    public Action<T> ProcessorAction { get; set; }

    public void ProcessMessage(IMessage message) {
        var msg = message as T;
        ProcessorAction(msg);
    }
}

public interface IMessageProcessor {
    void ProcessMessage(IMessage message);
}

public class MessageAProcessor : MessageProcessorBase<MessageA>,IMessageProcessor {
}

public class MessageBProcessor : MessageProcessorBase<MessageB>,IMessageProcessor {
}

public class MessageCProcessor : MessageProcessorBase<MessageC>,IMessageProcessor {
}

和处理器:

var processors = new List<IMessageProcessor>();
processors.Add(new MessageAProcessor());
processors.Add(new MessageBProcessor());
processors.Add(new MessageCProcessor());

由于ISomething<Type1>ISomething<Type2>之间没有继承关系,因此无法获得包含这些类型的混合对象的列表。

唯一的真实选择是强制某种基本类型-使用List<object>或更好地为IMessageProcessor<T>提供基本的非通用接口,例如IMessageProcessor<T> : IMessageProcessor

不幸的是,这也意味着如果没有强制类型转换,您将无法使用泛型访问属性/参数。

我不确定您要完成什么,但是您的代码确实无法正常工作。

我做了以下事情:

public class MessageAProcessor : MessageProcessorBase<MessageBase> { }
public class MessageBProcessor : MessageProcessorBase<MessageBase> { }
public class MessageCProcessor : MessageProcessorBase<MessageBase> { }

接着:

var processors = new List<MessageProcessorBase<MessageBase>> ();
processors.Add(new MessageAProcessor());
processors.Add(new MessageBProcessor());
processors.Add(new MessageCProcessor());

将工作。

问题是

public class MessageAProcessor : MessageProcessorBase<MessageA> { }

太具体了,您不能将其回退到List<>中的MessageProcessorBase<MessageBase> List<>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM