【发布时间】:2016-09-19 10:07:08
【问题描述】:
我正在尝试将此workaround 调整到我的项目中。而不是string,我想给基本构造函数一个object(RevitFamily 类型)。
不幸的是,我不知道如何使用Reflection.Emit 将object 或object 引用加载到堆栈中。谁能帮我?
到目前为止,我的代码看起来像这样,但我无法将object 传递给gen.Emit(opcode, _):
TypeBuilder tb = mb.DefineType(newtypename, new TypeAttributes(), typeof(LoadFamily));
var ci = typeof(LoadFamily).GetConstructor(new[] { typeof(RevitFamily) });
var constructorBuilder = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[0]);
var gen = constructorBuilder.GetILGenerator();
gen.DeclareLocal(typeof(RevitFamily));
Label ilLabel = gen.DefineLabel();
gen.Emit(OpCodes.Ldarg_0); // Load "this" onto eval stack
// Here I should some how get he object f in the stack....
gen.Emit(OpCodes.Ldloca, f); // Load pointer to RevitFamily on stack
gen.Emit(OpCodes.Call, ci); // call base constructor (consumes "this" and the string)
gen.Emit(OpCodes.Nop); // Fill some space - this is how it is generated for equivalent C# code
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ret); // return from constructor
t = tb.CreateType();
应该用类似这样的构造函数来创建动态类型:
public class LoadconcreteFamily : LoadFamily
{
public LoadconcreteFamily() : base(f)
{ }
}
【问题讨论】:
-
您是否已经在某处拥有所需类型的对象,或者您想创建一个新对象然后传递它?
-
该代码不会自行编译,因为
f没有在任何地方声明。出于同样的原因,您在发出 IL 时遇到了麻烦。您无法加载对在堆栈上生成的代码在 之外创建的本地对象的引用。也可以生成代码来创建对象,或者从字段加载引用,或者从传递给生成方法的参数加载引用。一旦您将对象存储在某个字段、本地或参数中,通常的ldarg/ldfld操作码就会应用。 -
@thehennyy: 是的,f 是一个对象,以这段代码段为参数赋予函数。
-
@JeroenMostert:谢谢...。我想,我明白了,为什么我想要达到的目标不能完成。
标签: c# reflection cil revit-api emit