我正在使用F#中的Reflection Emit进行一些黑客技术。我试图做与此C#代码相当的事情:
var ass = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("Test"), AssemblyBuilderAccess.RunAndSave);
var mb = ass.DefineDynamicModule("Test", "Test.dll", false);
var t = mb.DefineType("Foo", TypeAttributes.Public, typeof(ValueType));
t.DefineField("foo", typeof(int*), FieldAttributes.Public);
t.CreateType();
ass.Save("Test.dll");
其中特别的一行是definefield行。在F#中,我能找到的最接近的是
let f = t.DefineField("foo", (typeof<nativeptr<int>>), FieldAttributes.Public)
然而,最终编译的字段编译成了IntPtr类型,而不是int*类型。(请注意,对于nativeint或任何其他类型,它都是IntPtr类型)
此外,我希望能够在程序中定义一个结构体,并在另一个结构体中使用Foo*,但显然在这种情况下(无论是在C#还是F#中),我都无法使用typeof。是否有一种方法可以从Type/TypeBuilder中将字段定义为Foo*?
在任何人指出这可能都是疯狂的(我也同意)之前,这是一个有趣的项目,我要找出自己可以生成多疯狂的代码,而C#可能不会让我这么做 :)
let p = typedefof>.MakeGenericType([|t :> Type|])
let f = t.DefineField("rec", p, FieldAttributes.Public)
则运行良好。我猜测ilsigptr有一些特殊之处,但是如果能够访问生成的结构体指针将会很棒。您有什么想法吗? - neil danson