Reputation: 4522
I want to create Func type with specified generic type arguments, something like that like, but only with one statement
Type create_type(Type[] types)
{
return typeof(Func<>).MakeGenericType(types); // error if types.Length != 1
return typeof(Func<,>).MakeGenericType(types); // error if types.Length != 2
return typeof(Func<,,>).MakeGenericType(types); // error if types.Length != 3
return typeof(Func<,,,>).MakeGenericType(types); // error if types.Length != 4
// ....
}
Of course, I can create auxuliary array:
var func_types = new Type[] { typeof(Func<>), typeof(Func<,>) , //...}
But this solution seems too ugly for me
Note: array of types can be long (up to 15) and I want to find elegant solution. Unfortunately, I am creating such type from meta data, written in another language
Upvotes: 4
Views: 2126
Reputation: 28809
Recall that generic types have names of the form T`N
, where N
is the number of generic parameters. So all Func
delegates have a systematic name that allows us to easily get the type:
Type create_type(Type[] types) {
return Type.GetType($"System.Func`{types.Length}").MakeGenericType(types);
}
No promises as to how efficient this is, but if you're constructing such types at runtime, that's probably not the primary concern anyway.
Given the existence of Expression.GetFuncType
, this answer is of course inferior, but I'm leaving it up for educational purposes (of some sort). This stops working beyond 9 arguments, because System.Func
delegates of more than 9 arguments live in System.Core
, not mscorlib
, and therefore require an assembly-qualified name. The fix is easy (throw in a check and conditionally add System.Core
to the name), but unnecessary given the existence of GetFuncType
.
Upvotes: 2
Reputation: 9477
There are static Methods in Expression class for Func and Action that do exaclty what you require
Expression.GetFuncType(Type[] types)
Expression.GetActionType(Type[] types)
Further Information here:
Upvotes: 13