Reputation: 21855
I have the following generic class:
public class MessageProcesser<T> where T : Message
Inside the code I have the following attribute:
private readonly BlockingCollection<T> _messages;
When I try to do this I get an error (and as T is a Message it should be possible):
_messages.Add(new Message(MessageType.Stop));
What's wrong?
Thanks!
Upvotes: 2
Views: 173
Reputation: 64517
The compiler error is the fact that you assume T
is always Message
. T
could be a more derived type, like DerivedMessage : Message
. This would make your collection BlockingCollection<DerivedMessage>
, trying to set an instance of Message
into this would be invalid.
If you want to contain a list of all messages regardless of type, all you need to do is have:
private readonly BlockingCollection<Message> _messages;
And completely remove the use of generics. You can then store Message
types and any type that derives from Message
.
If you want to have MessageProcessor<T>
handle any message and store the correct, relevant type, you could always use the new()
constraint that forces the type to have a public parameterless constructor:
public class MessageProcesser<T> where T : Message, new()
Then you can perhaps do this:
var message = new T();
message.MessageType = MessageType.Stop;
_messages.Add(message);
You cannot constrain on constructors with arguments, so your current constructor use would not be supportable. A way around this is to pass a MessageFactory
to the MessageProcessor
and abstract creation responsibility to the factory.
Upvotes: 3
Reputation: 64628
You don't have a collection of messages. Message can't be T, because T may have been inherited.
try
private readonly BlockingCollection<Message> _messages;
Upvotes: 4