What's the best way to instantiate a generic from its name?
-
02-07-2019 - |
Question
Assuming I have only the class name of a generic as a string in the form of "MyCustomGenericCollection(of MyCustomObjectClass)" and don't know the assembly it comes from, what is the easiest way to create an instance of that object?
If it helps, I know that the class implements IMyCustomInterface and is from an assembly loaded into the current AppDomain.
Markus Olsson gave an excellent example here, but I don't see how to apply it to generics.
Solution
Once you parse it up, use Type.GetType(string) to get a reference to the types involved, then use Type.MakeGenericType(Type[]) to construct the specific generic type you need. Then, use Type.GetConstructor(Type[]) to get a reference to a constructor for the specific generic type, and finally call ConstructorInfo.Invoke to get an instance of the object.
Type t1 = Type.GetType("MyCustomGenericCollection");
Type t2 = Type.GetType("MyCustomObjectClass");
Type t3 = t1.MakeGenericType(new Type[] { t2 });
ConstructorInfo ci = t3.GetConstructor(Type.EmptyTypes);
object obj = ci.Invoke(null);
OTHER TIPS
The MSDN article How to: Examine and Instantiate Generic Types with Reflection describes how you can use Reflection to create an instance of a generic Type. Using that in conjunction with Marksus's sample should hopefully get you started.
If you don't mind translating to VB.NET, something like this should work
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
// find the type of the item
Type itemType = assembly.GetType("MyCustomObjectClass", false);
// if we didnt find it, go to the next assembly
if (itemType == null)
{
continue;
}
// Now create a generic type for the collection
Type colType = assembly.GetType("MyCusomgGenericCollection").MakeGenericType(itemType);;
IMyCustomInterface result = (IMyCustomInterface)Activator.CreateInstance(colType);
break;
}