1

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?

Community
  • 1
  • 1
Kasper Hansen
  • 6,307
  • 21
  • 70
  • 106

3 Answers3

1

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).

D Stanley
  • 149,601
  • 11
  • 178
  • 240
0

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

jason
  • 236,483
  • 35
  • 423
  • 525
  • @zimdanen: Yes, you can construct them at runtime using reflection, but you won't have the compile-time strong typing of generics. **That is, you lose all the compile-time advantages of using generics in the first place**. So, not really. – jason Jun 24 '13 at 14:31
0

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

Viktor Lova
  • 4,776
  • 2
  • 19
  • 25