1

I have a generic class GenericClass<T> for some reason I need to pass the generic type from another type like that:

say I have some classes from NormalClass1 to NormalClassN all of them have property say prop1 with different types I need to do this

var type1 = typeof(NormalClass1).GetProperty("prop1").GetType();

and send type1 to new instance of GenericClass like that:

 var instance = new GenericClass<type1>();

but an error has occurred that says that

Cannot implicitly convert type 'GenericClass<type1>' to 'GenericClass<T>'   

how can I pass this type to GenericClass

Abraham Josef
  • 653
  • 1
  • 8
  • 30
  • Have you tried converting it to T first? If `NormalClass1.prop1` is of type or inhertited from `T` then just convert it to `T` explicitly. If it is not inherited from `T` then you obviously cannot do this. – Yeldar Kurmangaliyev May 26 '15 at 08:45
  • You only know the generic type at runtime so you need the runtime features to create the generic type. You can't use new here that way. Something like `typeof(GenericClass<>).MakeGenericType(type1)` – Ralf May 26 '15 at 08:50
  • 1
    Sorry, I have misunderstood you. Your question is much more interesting :) Take a look at these: http://stackoverflow.com/questions/6562685/pass-type-to-generic-method-nested-generic http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method http://stackoverflow.com/questions/9666064/c-sharp-get-type-parameter-at-runtime-to-pass-into-a-generic-method – Yeldar Kurmangaliyev May 26 '15 at 08:57

2 Answers2

1

You can only do it with Reflection:

    var generic = typeof (GenericClass<T>).MakeGenericType(type1);
    var instance = Activator.CreateInstance(generic);
Vitaliy Gorbenko
  • 490
  • 4
  • 14
1

There are multiple problems with your code. First of all:

var type1 = typeof(NormalClass1).GetProperty("prop1").GetType();

will return the type PropertyInfo, not the type of the property. What you want is:

var type1 = typeof(NormalClass1).GetProperty("prop1").PropertyType;

Second of all you seem to have a conceptual issue with Generics, Types and TypeParameters.

Basically there is a difference between a Type variable (Type x = typeof(NormalClass1<>) and a generic Type parameter (the T in NormalClass<T>). T is not much more than a placeholder for a Type. You can use typeof(T) to get the actual Type of T. Using typeof(x) on the other hand would result in a compulation error since x is a variable and not a Type. You would use x.GetType() instead.

You cannot create a generic type via a runtime type variable directly. What you can do instead is creating the generic type via reflection.

The following example should illustrate how to do that

var genericTypeParameter = typeof(NormalClass1).GetProperty("prop1").PropertyType;
var genericBaseType = typeof(GenericClass<>);
var genericType = genericBaseType.MakeGenericType(genericTypeParameter);
var instance = Activator.CreateInstance(genericType);

As you can see, var instance would substitute to object instance. That has to be that way, since you can check the type of compile time. Best Practice would probably be to create a non generic base class for you generic class. You can than use the base class type and have at least a small amount of type checking at runtime, even if you have no chance to test the generic type parameter.

This would be what it would look like:

var instance = (GenericClassBase)Activator.CreateInstance(genericType);
crazy_crank
  • 659
  • 4
  • 17