2

I am trying to refactor some code by introducing generics, and I got stuck. I am trying to create a new instance of T, but the trouble is, that T has a delegate argument in the constructor. What I was aiming for was something like this:

public delegate IOrders DoStuffDelegate(); 


public class GenericBoss<T> where T:Worker
{

    public void DelegateWork()
    {
        T worker = Activator.CreateInstance(typeof(T), new[]{GiveOrders})
        worker.Work();
    }

    public IOrders GiveOrders()
    {
        return new OrderFromTheBoss();
    }
}

public class Worker
{
    private readonly DoStuffDelegate _takeOrders;

    public Worker(DoStuffDelegate takeOrders)
    {
        _takeOrders = takeOrders;
    }

    public void Work()
    {
        _takeOrders(); 
    }
}

However, this doesn't work, as only [object] types are allowed as arguments in the [Activator]. I am not allowed to change the constructor, so moving the delegate elsewhere is not possible.

Is there a way out, or is generics not an option here?

Regards, Morten

1 Answer 1

3

The problem is that the compiler doesn't know which delegate you want to convert your method group to. If it's always the DoStuffDelegate, you can just do this:

object[] args = new object[] { new DoStuffDelegate(GiveOrders) };
T worker = (T) Activator.CreateInstance(typeof(T), args);

or

DoStuffDelegate giveOrders = GiveOrders;
object[] args = new object[] { giveOrders };
T worker = (T) Activator.CreateInstance(typeof(T), args);

If the delegate type is different for each T, it's harder - you'd probably need to call Delegate.CreateDelegate to create an instance of the appropriate delegate type, discovered via reflection :(

Sign up to request clarification or add additional context in comments.

3 Comments

I think Activator.CreateInstance returns an object in this case? An as cast or the generic version should be applied.
@Danny: Yes, the cast would be required - will add that in. I was focusing on the arguments side of things, which I think is the OP's original issue :)
Yes, I had to cast it back to T, but then it worked. Thank you. You just made my code much prettier :o)

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.