7

I got a custom class, who relies on a generic type T to be passed along. I only know what type it is in string form, because that's how it's being sent. I've been searching around but can't seem to find exactly what I need. I can parse the string value to a type, but I need to parse it to... something, that I can pass as a generic parameter.


I've rewritten my problem, as such:

// Classes structure
namespace Mynamespace
{
    public interface IRequest
    {
    }

    public interface IHandler<T> where T : IRequest
    {
        void Handle(T item);
    }

    public class MyRequest : IRequest
    {
    }

    public class MyHandler : IHandler<MyRequest>
    {
        void Handle(MyRequest item)
        {
        }
    }
}

// The info I get, and I know typeString is a IRequest
string typeString = "My";
object requestItem = [insert xml parsing here];

// I then create a handler, to handle the request
Type typeHandler = Type.GetType("Mynamespace." + typeString + "Handler");
var handler = Activator.CreateInstance(typeHandler);

Type typeRequest = Type.GetType("Mynamespace." + typeString + "Request");

// what I want to do:
handler.Handle(requestItem);

I can't do that because handler and requestItem are just objects So I need to parse 'handler' to 'typeHandler', and requestItem to 'typeRequest'

Edit: I figured it out, I used InvokeMember to access it. :)

typeHandler.InvokeMember("Handle", BindingFlags.InvokeMethod, null, handler, new[] { requestItem });

3 Answers 3

10

You need Type.MakeGenericType:

Type typeArgument = Type.GetType(string.Format("Mynamespace.{0}", typeString));
Type template = typeof(MyClass<>);

Type genericType = template.MakeGenericType(typeArgument);

object instance = Activator.CreateInstance(genericType);

Note that you can't cast this to a particular MyClass<T> because you don't know T - but it will be an instance of the right class at execution time.

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

7 Comments

+1. Also note that, although you can't cast the result to a particular MyClass<T>, you may want to define a non-generic interface (e.g. IMyClass) and cast to that.
@Daniel: Indeed. I thought I'd hold back from that until the OP gave more information :)
This is what I sort of do as well already, to create a new instance. But that returns an object, and that object, I need to parse to a MyClass<T>. Because the 'MyClass' has a void that requires the T.
@Daniel: In my real code I use an interface, and an extra class in between, but I tried here to make a sample of what my problem is, without making it too complicated. :)
@FrieK: What do you mean, "has a void that requires the T"? You aren't going to be able to use compile-time generic dispatch based on a type that is only determined at run time -- it's simply not possible. Perhaps dynamic will do what you want, but I don't understand your problem well enough to be sure.
|
4
Type closedType = typeof(MyClass<>).MakeGenericType(myGeneric);
object obj = Activator.CreateInstance(closedType);

Note that unless you have a non-generic interface or base-type, it is very tricky to talk to this type of object (unless you cheat by using dynamic). For example, a non-generic interface can be helpful:

var obj = (ISomeInterface)Activator.CreateInstance(closedType);
obj.SomeMethodOnTheNonGenericInterface();

Comments

1

I figured it out, I used InvokeMember to access it. :)

typeHandler.InvokeMember("Handle", BindingFlags.InvokeMethod, null, handler, new[] { requestItem });

Comments

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.