3

我一直在为 .NET 开发一种自定义语言的编译器,它目前使用 System.Reflection.Emit 但是当我想在 Mono 上运行它时(它在 MS .NET 上运行良好,2.0 和 4.0 CLR)我运行在处理 GenericTypeParameterBuilder 时会遇到一堆异常,最具体地说是这个:

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 

现在运行它的代码非常复杂,因此很难复制粘贴特定的代码,但我尝试编译的代码结构如下所示:

public class Foo<T> { }
public class Bar<T> : Foo<T> { }

当我尝试编译应该从 Foo<T> 继承的 Bar<T> 类时会出现问题,其中提供给 Foo 的通用参数是来自 bar 的 T。

所以我的问题是:这是 Mono SRE 中的一个已知问题吗?有没有办法解决这个问题?它是否固定在新的单声道测试版或其他东西中?

4

2 回答 2

2

这当然看起来像一个错误。似乎DefineDefaultConstructor在设置父类型之前显式调用子类型的类型构建器并调用CreateType将解决它,至少在最简单的情况下是这样。

编辑

或者,为子类型显式定义构造函数(可能只是调用基本构造函数并返回)看起来即使在设置父类型之后它也可以工作,因此这可能是一种更好的方法。

于 2013-02-05T17:10:49.787 回答
0

我试图在从 git 编译的最新单声道上复制此问题,但无法复制此问题。它可能已经被修复了。我使用的代码:

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();
于 2013-02-08T14:57:57.527 回答