Search code examples
c#dynamicdequecreateinstanceconcurrent-queue

concurrentQueue tryDequeue with unknown out result


I'm trying to build a flexible method to handle different kind of ConcurrentQueues, 'cause most logic to handle the queue's is the same.

It looks a bit like this:

private void StartDoWorkButton(object sender, EventArgs e)
    {
        StartDoWork();
    }

    private ConcurrentQueue<TestData> myQueue = new ConcurrentQueue<TestData>();
    private void StartDoWork()
    {
        DoWork(myQueue, new TestData());
    }

    private void DoWork(dynamic queue,object objectType)
    {
        dynamic outResult = Activator.CreateInstance(objectType.GetType());
        while(queue.TryDequeue(out outResult))
        {
            //do something
        }
    }

The outResult seems to be of the correct type, but I get this message:"The best overloaded method match for 'System.Collections.Concurrent.ConcurrentQueue.TryDequeue(out WinformWith10pxNewProject1.TestData)' has some invalid arguments"

Thing is, it works fine when I do this:

    private void DoWork(dynamic queue,object objectType)
    {
        TestData outResult;// hardcoded type
        while(queue.TryDequeue(out outResult))
        {
            //do something
        }
    }

Is there any way I can work around the hard coding of the type? Would give me a lot of flexibility for the methods I'm creating.

Kind regards,

Matthijs


Solution

  • I would use a generic method for this:

    private void DoWork<T>(ConcurrentQueue<T> queue,object objectType)
    {
        T outResult;// generic type
        while(queue.TryDequeue(out outResult))
        {
            //do something
        }
    }
    

    This way you can use any type of the ConcurrentQueue< T>.

    And you can call it like: (same as the hardcoded veriant)

    private void StartDoWork()
    {
        DoWork(myQueue, new TestData());
    }
    

    If you need the < T> to be of a specific basetype or interface, you can create constrains on it:

    private void DoWork<T>(ConcurrentQueue<T> queue,object objectType) where T: IDisposable
    {
        T outResult;// generic type
    
        while(queue.TryDequeue(out outResult))
        {
            //do something
    
            outResult.Dispose();
        }
    }
    

    The IDisposable is for example. So you're able to call the Dispose method (from the IDisposable)