If I understand correctly what you want, you have two Type
s, let's call them T1<>
and T2
and you want to create an instance of the type T1<T2>
.
For that, you don't need any expression trees, just call MakeGenericType()
directly and then use Activator.CreateInstance()
:
public static object CreateGenericInstance(
Type genericTypeDefinition, Type genericParameter)
{
var genericType = genericTypeDefinition.MakeGenericType(genericParameter);
return Activator.CreateInstance(genericType);
}
If Activator.CreateInstance()
is too slow for you (and you should measure that it actually is too slow), then you could replace it with cached lambdas:
Dictionary<Tuple<Type, Type>, Func<object>> instanceCreatorCache
= new Dictionary<Tuple<Type, Type>, Func<object>>();
object CreateGenericInstance(Type genericTypeDefinition, Type genericParameter)
{
Func<object> instanceCreator;
var cacheKey = Tuple.Create(genericTypeDefinition, genericParameter);
if (!instanceCreatorCache.TryGetValue(cacheKey, out instanceCreator))
{
var genericType = genericTypeDefinition.MakeGenericType(genericParameter);
instanceCreator = Expression.Lambda<Func<object>>(
Expression.New(genericType)).Compile();
instanceCreatorCache[cacheKey] = instanceCreator;
}
return instanceCreator();
}
I decided to also avoid the call to MakeGenericType()
when the type is already in cache, but I have no idea whether that would actually improve performance.