簡體   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