无法将新实例添加到泛型类中的泛型列表中。为什么?

时间:2012-06-14 07:46:39

标签: c# .net generics constraints

我有以下通用类:

public class MessageProcesser<T> where T : Message

在代码中我有以下属性:

private readonly BlockingCollection<T> _messages;

当我尝试这样做时,我收到一个错误(因为T是一个消息,它应该是可能的):

_messages.Add(new Message(MessageType.Stop));

怎么了?

谢谢!

2 个答案:

答案 0 :(得分:4)

您没有邮件集合。消息不能是T,因为T可能已被继承。

private readonly BlockingCollection<Message> _messages;

答案 1 :(得分:3)

编译器错误是因为您假设T始终为MessageT可以是更多派生的类型,例如DerivedMessage : Message。这会使您的集合BlockingCollection<DerivedMessage>尝试将Message的实例设置为此内容无效。

如果要包含所有消息的列表而不管类型如何,您只需要:

private readonly BlockingCollection<Message> _messages;

并完全删除泛型的使用。然后,您可以存储Message类型以及从Message派生的任何类型。

如果您希望MessageProcessor<T>处理任何消息并存储正确的相关类型,您可以始终使用new()约束来强制该类型具有< strong> public parameterless 构造函数:

public class MessageProcesser<T> where T : Message, new()

然后你可以这样做:

var message = new T(); 
message.MessageType = MessageType.Stop;
_messages.Add(message);

不能约束带有参数的构造函数,因此你当前的构造函数使用是不可支持的。解决这个问题的方法是将MessageFactory传递给工厂的MessageProcessor抽象创建责任。