简体   繁体   中英

Instantiating a generic type from string

I want to Instantiate a generic type from string and have done the following:

    private static void APERAK(string content, PartyElement pe, bool reload)
    {
        Type t = typeof(Serializer<>).MakeGenericType(Type.GetType(GetMessageTypeVersion(content)));
        Serializer<t> serializer = new Serializer<t>();
    }

    private static string GetMessageTypeVersion(string content)
    {
        //TODO
        return "APERAK";
    }

But in

Serializer<t> serializer = new Serializer<t>();

it says that "The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?)" before compiling. But I want to instantiate the Serializer based on the string found. How can I do this?

You already have a generic type with the following:

typeof(Serializer<>).MakeGenericType(...);

All you need to do is instantiate it:

object o = ACtivator.CreateInstance(t);

Of course the compiler will have no knowledge of what type t is, thus you will not be able to use its methods/properties without reflection, so generics doesn't really help you here. Best you can do is cast is to a non-generic base class of Serializer<> (assuming one exists).

Generics are a compile-time construct. You have to know what the type parameters are at compile time, not at runtime.

So, well, you really can't get all features of compile-time generics. Well, there are some another ways.

1) Instantiate generic type and pack it as object, then use reflection to call methods:

object t = Activator.CreateInstance(type);
var res = (string)type.GetMethod("Do").Invoke(t, new object[] { "abc" });

2) Instantiate generic type and convert it to dynamic object, then just use it (you lose intellisense and compile-time checks):

dynamic t = Activator.CreateInstance(type);
var res = (string)(t.Do("abc"));

3) Create temporary generict method and call it with reflection (you got intellisense and compile-time checks):

public static string UseSerializer<T>(Serializer<T> s)
{
   return s.Do("abc");
}

And then use it in such way:

var useSerializer = typeof(SomeStaticClass).GetMethod("UseSerializer")
object t = Activator.CreateInstance(type);
var res = useSerializer.Invoke(null, new object[]{t});

In addition, this methods can be sorted by time that they are executed: dynamic < temporary method < simpleReflection

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM