Brad Robinson
Brad Robinson

Reputation: 46807

How to get an open generic type from a string

I have a Type[] array and I want to get the Func type where T1, T2 etc... correspond to the types in the array. The array is not fixed in size but assume a type is available in the runtime (16 in .NET 4, 4 in .NET 3.5).

In .NET 4, I can do this and it works:

Type GetFuncType(Type typeRet, Type[] types)
{
    return Type.GetType(string.Format("System.Func`{0}", types.Length + 1))
                  .MakeGenericType(types.Concat(new Type[] { typeRet } ).ToArray())
}

In .NET 3.5 however, the Type.GetType for the open generic type fails, returning NULL.

Is there a way I make this work in .NET 3.5? My only thought atm is to build up a string for the close generic type.

Upvotes: 3

Views: 437

Answers (2)

Brad Robinson
Brad Robinson

Reputation: 46807

I've accepted Marc's answer to this because it's obviously the correct way to do it in this case. However in the mean time I worked out another solution which might be handy in other cases.

The problem with my original approach was related to the Func`{0} type name not being qualified with an assembly reference. So the alternate fix I found was this (typos not withstanding):

typeof(Func<>).Assembly.GetType(string.Format("Func`{0}", types.Length+1));

The typeof(Func<>).Assembly is a hack to get a reference to the assembly that implements the Func types.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062855

The preferred way of doing this is to use Expression.GetFuncType(Type[]) and Expression.GetActionType(Type[]). In the case of func, the last Type is the return, so:

Array.Resize(ref types, (types == null ? 0 : types.Length) + 1);
types[types.Length - 1] = typeRet;
return Expression.GetFuncType(types);

Upvotes: 4

Related Questions