简体   繁体   中英

passing type of property to generic type

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

You can only do it with Reflection:

    var generic = typeof (GenericClass<T>).MakeGenericType(type1);
    var instance = Activator.CreateInstance(generic);

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

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