0

I have some ugly code that looks something like this:

    switch (f.TypeName)
    {
        case "TypeOne":
            ThreadPool.QueueUserWorkItem(new WaitCallback(MyMethod<TypeOne>), args);
            break;
        case "TypeTwo":
            ThreadPool.QueueUserWorkItem(new WaitCallback(MyMethod<TypeTwo>), args);
            break;

        ...

        case "TypeTwenty":
            ThreadPool.QueueUserWorkItem(new WaitCallback(MyMethod<TypeTwenty>), args);
            break;
    }

I would really like to get rid of the switch statement and do something along these lines:

    var myTypeDescriptor = Type.GetType(f.TypeName); //<== clearly not this, but similar
    ThreadPool.QueueUserWorkItem(new WaitCallback(MyMethod<myTypeDescriptor>), args);

where MyMethod looks like this:

    protected void MyMethod<T>(object args)
    {
        ...
    }

I've poked around some and have found a number of examples where the generic is a generic class, but no examples where it is a generic method. And definitely not any examples where it is being passed to a delegate.

While this appears, at first glance, to be a duplicate of How do I use reflection to call a generic method?, I am not simply trying to call the method. It is being passed to the WaitCallback delegate. Perhaps this is a two part question: 1) how do I retrieve the generic method via reflection and 2) having obtained a handle to the method, how do I pass it as an argument to the WaitCallback delegate?

Anyone have any ideas? Is this even possible?

Steve Elmer
  • 939
  • 2
  • 10
  • 19
  • How are you using the generic parameter in `MyMethod`? Can you create a version which takes an explicit `Type` parameter? – Lee Nov 13 '17 at 21:42
  • can you show implementation of `MyMethod`? you oversimplified. if `T` is not used anywhere in input or output, then It feels like design problem and you are probably solving wrong problem. – M.kazem Akhgary Nov 13 '17 at 21:52

3 Answers3

1

Here is brief idea

var type = Type.GetType(f.TypeName);
var methodInfo = typeof(MethodHoderType).GetMethod("MyMethod");
var constructedMethodInfo = methodInfo.MakeGenericMethod(type);
constructedMethodInfo.Invoke(...);

If it is instance method you should create an instance of type type to pass to Invoke method or pass null as first parameter if it is static method.

Look at the Type.GetType Method (String) and MethodInfo.MakeGenericMethod Method (Type[]) for more information.

Hamlet Hakobyan
  • 32,965
  • 6
  • 52
  • 68
0

If you can create instances of the types from the strings you have (if you know them fully qualified), you can use MethodInfo.MakeGenericMethod(Type[] typeArguments)

Take a look at the docs in MSDN.

Waescher
  • 5,361
  • 3
  • 34
  • 51
0

Hope this Helps. Instead of a string Just build a decorator to take in the Type that Queues the Item.

class Program
{
    static void Main(string[] args)
    {
        var arguments = new object();

        Execute<ObjectA>(args);
        Execute<ObjectB>(args);
        Execute<ObjectC>(args);
        Execute<ObjectA>(args);

        Console.ReadLine();
    }

    static void Execute<T>(object args) where T:BaseObject
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(MyMethod<T>), args);
    }

    static void MyMethod<T>(object args) where T:BaseObject
    {
        Console.WriteLine(typeof(T).FullName);
    }
}

public class BaseObject
{
}

public class ObjectA : BaseObject
{
}

public class ObjectB : BaseObject
{
}

public class ObjectC : BaseObject
{
}

enter image description here

Viju
  • 95
  • 1
  • 7