views:

105

answers:

4

I have a method that receives messages from a queue of msmq.

I have 6 different queues in msmq and i d like a single generic method that would receive the messages. THis work, but i need to write 6 methods for each queue. I d like to make it more generic.

public List<QueMessage> getMessagesFromObj1Queue()
{
    List<QueMessage> messageList = new List<QueMessage>();

    QueObj1 que = new QueObj1();

    while (que.ReceiveAll().Count > 0)
    {
        varmessage = que.Receive(new TimeSpan(0, 1, 0));
        messageList.Add(message);
    }

    return messageList;
}

I have 5 different object which just extends a single abstract class. Below doenst work.

public List<QueMessage> getMessagesFromObj1Queue<T>(T que)
{
    List<QueMessage> messageList = new List<QueMessage>();

    while (que.ReceiveAll().Count > 0)
    {
        varmessage = que.Receive(new TimeSpan(0, 1, 0));
        messageList.Add(message);
    }

    return messageList;
}

Above doesnt work

how to fix this?

+3  A: 

The problem here is that you've told the C# compiler nothing about the type of que and hence it must treat it as an object. You must provide more information so that it can properly bind the Receive method.

This can be done by adding a generic constraint to the method. For example

public List<QueMessage> getMessagesFromObj1Queue<T>(T que) 
  where T : [InsertBaseTypeOfQues]
JaredPar
+5  A: 

If T in your example is some base class that all queue objects inherit, then you can just pass that to the method instead of T:

public List<QueMessage> getMessagesFromObj1Queue<T>(QueueObjBase que) { ... }

Otherwise, if there's come common interface that all T's will implement, use that as a generic constraint:

public List<QueMessage> getMessagesFromObj1Queue<T>(T que) 
   where T : [yourInterface]
{
}

Without a generic constraint on T, the compiler doesn't have any information to know what method or properties are available, and so can only treat T as object - which, of course, doesn't have a RecieveAll() method.

LBushkin
I dont have interface but a single abstract class.
If that's the case, then just pass that abstract type to the method directly. I assume that `ReceiveAll()` already returns instances of `QueMessage`.
LBushkin
+1  A: 

Add a where contraint onto the method and delcare the type param to be your base class.

where T : The type argument must be or derive from the specified base class.

see generic type constrains from msdn

almog.ori
A: 

As it is, the type T has no ReceiveAll method. You need to add a constraint, so that the compiler knows that the method exists, for any instantiation of T. So, you'd get:

public List getMessagesFromObj1Queue(T que) : where T : XXX

I don't know MSMQ enough to know what XXX should be, though.

Timores