Instantiating generic types at runtime using reflection
Tags: csharp, reflection
Published: 2019-06-09 12:43:03

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

```c#
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.