Generic class from type parameter

c#, generics, types

Solution

If you know the type you actually want (`OneMoreClass`) at build time, then you should just use it:

var generic = GenericClass.GetInstance<OneMoreClass>();

But I am assuming you don't know it at build time, and have to get the `type` at runtime. You can do it with reflection, but it isn't pretty, and is slow:

public class GenericClass
{
    public static object GetInstance(Type type)
    {
        var genericType = typeof(GenericClass<>).MakeGenericType(type);
        return Activator.CreateInstance(genericType);
    }
}

Since you don't know the resulting type at build time, you can't return anything but `object` (or `dynamic`) from the method.

Here is how much slower (for 100,000 creates)

public class GenericClass
{
    public static object GetInstance(Type type)
    {
        var genericType = typeof(GenericClass<>).MakeGenericType(type);
        return Activator.CreateInstance(genericType);
    }

    public static GenericClass<T> GetInstance<T>()
        where T : class
    {
        return new GenericClass<T>();
    }
}

    [Test]
    public void CanMakeGenericViaReflection_ButItsSlow()
    {
        var timer = new Stopwatch();
        var SC = new SomeClass();
        SC.TypeOfAnotherClass = typeof(OneMoreClass);

        timer.Start();
        for (int x = 0; x < 100000; x++)
        {
            GenericClass.GetInstance(SC.TypeOfAnotherClass);
        }
        timer.Stop();
        Console.WriteLine("With Reflection: " + timer.ElapsedMilliseconds + "ms.");

        timer.Restart();
        for (int x = 0; x < 100000; x++)
        {
            GenericClass.GetInstance<OneMoreClass>();
        }
        timer.Stop();
        Console.WriteLine("Without Reflection: " + timer.ElapsedMilliseconds + "ms.");
    }

Results:

With Reflection: 243ms.
Without Reflection: 2ms.

So a little over 100x slower.

The real thing to note about generics is that the `<T>`s in generics are resolved at build-time by the C# compiler, and the real class names are inserted. When you have to defer that until run-time, you end up paying the performance price.

Problem

Is there a way to create a generic class from type parameter. I have something like this: ``` public class SomeClass { public Type TypeOfAnotherClass { get; set; } } public class OneMoreClass { } public class GenericClass<T> where T : class { public void DoNothing() {} } public class GenericClass { public static GenericClass<T> GetInstance<T>(T ignored) where T : class { return new GenericClass<T>(); } } ``` What I want is to create a GenericClass from a Type. Ex: ``` var SC = new SomeClass(); SC.TypeOfAnotherClass = typeof(OneMoreClass); var generic = GenericClass.GetInstance(SC.TypeOfAnotherClass); Assert.AreEqual(typeof(GenericClass<OneMoreClass>), generic.GetType()); ``` Here I expect to get instance of `GenericClass<OneMoreClass>` but I get `GenericClass<Type>` I also tried using instance of that type. Ex: ``` var generic = GenericClass.GetInstance(Activator.CreateInstance(SC.TypeOfAnotherClass)); ``` This time I get `GenericClass<object>` Is there a way to accomplish this task?

Original source