Inconsistent support for Reflection.Emit in Mono?
I'm working on a compiler for a custom .NET language that currently uses System.Reflection.Emit, but when I want to run it in Mono (it works fine on MS.NET, both CLR 2.0 and 4.0) I ran into a bunch of exceptions when working with GenericTypeParameterBuilder, most specifically this:
Unhandled Exception: System.NotSupportedException: The invoked member is not supported in a dynamic module.
at System.Reflection.Emit.TypeBuilder.check_created () [0x00012] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.9\mcs\class\corlib\System.Reflection.Emit\TypeBuilder.cs:1678
at System.Reflection.Emit.TypeBuilder.InternalResolve () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.9\mcs\class\corlib\System.Reflection.Emit\TypeBuilder.cs:1653
at System.Reflection.Emit.GenericTypeParameterBuilder.InternalResolve () [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.9\mcs\class\corlib\System.Reflection.Emit\GenericTypeParameterBuilder.cs:93
at System.Reflection.MonoGenericClass.InternalResolve () [0x00021] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.9\mcs\class\corlib\System.Reflection\MonoGenericClass.cs:105
at System.Reflection.Emit.TypeBuilder.DefineDefaultConstructor (MethodAttributes attributes) [0x00030] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.9\mcs\class\corlib\System.Reflection.Emit\TypeBuilder.cs:484
at System.Reflection.Emit.TypeBuilder.CreateType () [0x0017f] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.9\mcs\class\corlib\System.Reflection.Emit\TypeBuilder.cs:788
at dotC.CType.CreateType () [0x00000] in <filename unknown>:0
at dotC.Compiler.Save () [0x00000] in <filename unknown>:0
at dotC.Compiler.Compile () [0x00000] in <filename unknown>:0
at dotC.Dev.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0
Now the code that runs this is quite involved, so it is difficult to copy-paste a specific piece of code, but the structure of the code I'm trying to compile is like this:
public class Foo<T> { }
public class Bar<T> : Foo<T> { }
And the problem comes when I try to compile the Bar & lt> T class, which must inherit from Foo <T>, where the generic parameter provided by Foo is T from string.
So my question is, is this a known issue in Mono SRE? Is there a way to get around this? Is this fixed in the new beta mono or something else etc.?
source to share
This, of course, looks like a bug. It looks like an explicit call DefineDefaultConstructor
in the type builder of the child type before the parent type is set and the call CreateType
will work around it, at least in the simplest case.
EDIT
Alternatively, explicitly defining the constructor of the child type (which potentially just calls the base constructor and returns) looks like it works even after setting the parent type, so this might be a better approach.
source to share
I tried to replicate this issue on the latest monomial compiled from git and was unable to replicate this issue. It may have already been fixed. The code I used:
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("test"), AssemblyBuilderAccess.RunAndSave);
var module = assembly.DefineDynamicModule("test.dll");
var foo = module.DefineType("Foo");
foo.DefineGenericParameters("T");
var bar = module.DefineType("Bar");
bar.DefineGenericParameters("T");
bar.SetParent(foo);
foo.CreateType();
bar.CreateType();
source to share