Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you instantiate a template class at runtime using C#

Is it possible to instantiate a template class at runtime for example:

Type type = Type.GetType("iTry.Workflow.Person");
WorkflowPropertyViewModel<type> propViewModel = new WorkflowPropertyViewModel<type>();

This obviously does not work. Is there some other way to do it?

The Generic class looks like the following:

public class WorkflowPropertyViewModel<T> : IProperty<T>  
{
    public Task<T> ValueAsync
    {
        get;
        set;
    }

    public T Value
    {
        get;
        set;
    }

    public IQueryable<T> PossibleItems
    {
        get;
        set;
    }
}
like image 229
Bracher Avatar asked Nov 22 '12 12:11

Bracher


2 Answers

You can create an object of any type given a Type object:

object o = Activator.CreateInstance(type);

This assumes the type has a default constructor. There are other Activator methods for passing constructor parameters:

http://msdn.microsoft.com/en-us/library/wccyzw83.aspx

In order to get a specific generic type you can call MakeGenericType on your generic type definition

http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx

So putting it altogether it looks something like:

var type = Type.GetType("iTry.Workflow.Person");
var genericType = typeof(WorkflowPropertyViewModel<>).MakeGenericType(type);
var o = Activator.CreateInstance(genericType);
like image 131
James Gaunt Avatar answered Sep 28 '22 15:09

James Gaunt


Yes, you can instantiate a generic class with a type known only at runtime, e.g.:

public class A { }
public class U<T> {
    public T X { get; set; }
}

static void Main(string[] args) {
    Type a = typeof(A);
    Type u = typeof(U<>);
    dynamic uOfA = Activator.CreateInstance(u.MakeGenericType(a));
    uOfA.X = new A();
    Console.WriteLine(uOfA.GetType());
    Console.WriteLine(uOfA.X.GetType());
}

However, this snippet uses reflection and dynamic typing, both of which may cause a lot of maintenance problems, so you would be better off using them very carefully or finding a simpler solution.

like image 45
Andrew Sklyarevsky Avatar answered Sep 28 '22 15:09

Andrew Sklyarevsky