Search code examples
c#genericsdynamicexpression-trees

Doesn't Expression Tree support dynamic generic type parameters?


I'd like to dynamically create generic classes. To define type parameters you will call DefineGenericParameters method on TypeBuilders and you can add type constraints on the type parameters with the return value.

By the way, I'm using Expression Tree to emit the method body. But then I realized that the APIs of Expression Tree don't accept GenericTypeParameterBuilders, which is the return value of the DefineGenericParameters method, as arguments.
Maybe you are wondering whether it will compile. Because the type is derived from Type so it will compile. But the APIs of Expression Tree throw exceptions at runtime, telling me that the type contains a generic type parameter on Mono and that the method is not supported on .NET.

So it seems to me that Expression Tree can't handle generic type parameters, but is it really so? Am I missing something?
If so, I will be happy if you are suggesting other ways to handle generic type parameters using Expression Tree.


Solution

  • the method is not supported on .NET.

    This I can explain:

    To check if the type is an enum, in the end this line is called:

    public override bool IsSubclassOf(Type c)
    {
        throw new NotSupportedException();
    }
    

    by this line:

     public virtual bool IsEnum {
         get
         {
            return IsSubclassOf(RuntimeType.EnumType);
         }
    

    that is called by this line:

    internal static ParameterExpression Make(Type type, string name, bool isByRef) {
        if (isByRef) {
            return new ByRefParameterExpression(type, name);
        } else {
            if (!type.IsEnum) {
    

    Now... About your question: no can do. Sadly the two subsystems (Reflection.Emit and Expression) aren't much "compatible". As you know creating instance methods (including constructors) with LambaExpression.CompileToMethod() isn't supported. The only thing you can do is create plain (non-generic) static methods that don't include the type being constructed with TypeBuilder in its parameters.