2

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!

1
  • Why do you need generics for this?? Commented Jun 14, 2012 at 7:50

2 Answers 2

4

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;
Sign up to request clarification or add additional context in comments.

2 Comments

+1 Indeed, to say it another way, although the OP states where T : Message. T might be DerivedMessage : Message so adding Message to a BlockingCollection<DerivedMessage> is invalid. However, adding DerivedMessage to a BlockingCollection<Message> is valid and perhaps what the OP was trying do to.
Thanks, you're right. The MessageProcessor should process Messages, not T.
3

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.

2 Comments

I could accept your answer too ... the other one was higher on the page :P
@SoMoS Entirely up to you, I'm not fussed :-) I was only trying to complement his answer with further detail.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.