Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically Create a generic type for template

Tags:

c#

generics

I'm programming WCF using the ChannelFactory which expects a type in order to call the CreateChannel method. For example:

IProxy proxy = ChannelFactory<IProxy>.CreateChannel(...);

In my case I'm doing routing so I don't know what type my channel factory will be using. I can parse a message header to determine the type but I hit a brick wall there because even if I have an instance of Type I can't pass that where ChannelFactory expects a generic type.

Another way of restating this problem in very simple terms would be that I'm attempting to do something like this:

string listtype = Console.ReadLine(); // say "System.Int32"
Type t = Type.GetType( listtype);
List<t> myIntegers = new List<>(); // does not compile, expects a "type"
List<typeof(t)> myIntegers = new List<typeof(t)>(); // interesting - type must resolve at compile time?

Is there an approach to this I can leverage within C#?

like image 373
t3rse Avatar asked Sep 15 '08 21:09

t3rse


People also ask

Can dynamic type be used for generic?

Not really. You need to use reflection, basically. Generics are really aimed at static typing rather than types only known at execution time.

How do you initialize a generic class?

The solution is to use the default keyword, which will return null for reference types and zero for numeric value types. For structs, it will return each member of the struct initialized to zero or null depending on whether they are value or reference types.

How do you indicate that a class has a generic type parameter?

A generic type is declared by specifying a type parameter in an angle brackets after a type name, e.g. TypeName<T> where T is a type parameter.


1 Answers

What you are looking for is MakeGenericType

string elementTypeName = Console.ReadLine();
Type elementType = Type.GetType(elementTypeName);
Type[] types = new Type[] { elementType };

Type listType = typeof(List<>);
Type genericType = listType.MakeGenericType(types);
IProxy  proxy = (IProxy)Activator.CreateInstance(genericType);

So what you are doing is getting the type-definition of the generic "template" class, then building a specialization of the type using your runtime-driving types.

like image 161
IDisposable Avatar answered Sep 21 '22 19:09

IDisposable