Instantiating generic types at runtime using reflection
Emanuel Vintila
Posted on June 9, 2019
In this post, we will see how we can instantiate generic types at runtime using reflection, and call methods on the instance with correct arguments.
Assume you want to have a List<T>
dynamically created at runtime; we do not want to create a List<object>
instance, we want our instance to have a runtime type of List<T>
. Well, of course T will be substituted with an actual type, like string
, or int
, depending on a user choice.
Note: there is no Exception handling; it is beyond the scope of the post.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
namespace Reflection
{
public class Program
{
private static void Main(string[] args)
{
Console.WriteLine("What type do you want your items to be? ");
string input = Console.ReadLine();
Type type = Type.GetType(input);
// this is called an unbound type
Type unbound = typeof(List<>);
// unbound.IsGenericType == true
Type bound = unbound.MakeGenericType(type);
// get parameterless constructor and invoke it
object list = bound.GetConstructor(new Type[0]).Invoke(new object[0]);
// cannot use nameof with unbound types
// string addMethod = nameof(List<>.Add);
// use any bound type instead
string methodNameAdd = nameof(List<object>.Add);
MethodInfo methodAdd = bound.GetMethod(methodNameAdd);
while (true)
{
Console.Write("Insert a new value into the list: ");
input = Console.ReadLine();
object arg = input;
if (type != typeof(string))
{
ConstructorInfo constructor = type.GetConstructor(new[] {typeof(string)});
// construct the type from a string
if (constructor != null)
arg = constructor.Invoke(new object[] {input});
// or call the static Parse method on C# primitive types
else
arg = type
// get the public static Parse method that accepts a string
.GetMethod("Parse", 0, BindingFlags.Static | BindingFlags.Public, null,
new[] {typeof(string)}, null)
.Invoke(null, new object[] {input});
}
methodAdd.Invoke(list, new[] {arg});
// display the list after adding the item
foreach (object item in (IEnumerable) list)
Console.Write($"{item} ");
Console.WriteLine();
}
}
}
}
We have specified that the compile-time type of the list
variable is object
, but it will be assigned a List<T>
that will be created using reflection.
We let the user choose what type they want their list to hold. This should be specified as a fully qualified name (e.g. System.Int32
). Then we add items to the list, transforming them into the appropriate type first.
Posted on June 9, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.