我现在使用System.Reflection.Emit一段时间了,发现它(谁没有?)像容易出错一样痛苦.
你知道IL Generator周围是否有一个好的包装器,我可以依赖它以比直接使用SRE更安全,更容易的方式发出IL吗?
编辑:
我知道操纵表达树比直接发射IL更容易和更安全,但它们现在也有一些限制.我不能创建代码块,使用循环,声明和使用几个本地,等等.我们需要等到.NET 4出来:)
此外,我正在处理已经依赖于SRE的代码库.
显然,ILGenerator会做我需要的一切.但是在操纵它时我会感激更多的帮助.当我指的是一个非常低级别的ILGenerator包装器时,我想到的东西可以提供如下方法:
// Performs a virtual or direct call on the method, depending if it is a
// virtual or a static one.
Call(MethodInfo methodInfo)
// Pushes the default value of the type on the stack, then emit
// the Ret opcode.
ReturnDefault(Type type)
// Test the object type to emit the corresponding push
// opcode (Ldstr, Ldc_I*, Ldc_R*, etc.)
LoadConstant(object o)
Run Code Online (Sandbox Code Playgroud)
这真的是3个天真的例子,但它足以证明我的期望.我们可以看到它作为一组扩展方法,但是在RunSharp中支持条件语句和循环可能会很好.实际上,RunSharp与我想要的非常接近,但它过多地抽象了ILGenerator并且没有公开它的所有功能.
我不记得在哪里,但我已经在开源项目中看到过这样的帮手.
基本上,我接受一个事件名称作为字符串,以获得EventInfo.然后,我发现使用反射的事件处理程序类型和事件参数类型,创建该类型的新委托(myEventHandler),并将其与事件挂钩.在myEventHandler调用时,我需要向下转换并将参数传递给处理程序.
我的代码如下.myEventHandler当调用'd'时,需要调用'handler' .我需要在那里放一些反射发射代码??? 有什么想法吗?
EventHandler handler = delegate(object sender, EventArgs eventArgs)
{
//something will happen here
};
Type[] typeArgs = { typeof(object), derivedEventArgsType };
DynamicMethod myEventHandler = new DynamicMethod("", typeof(void), typeArgs);
var ilgen = myEventHandler.GetILGenerator();
//What should be the IL code here to
//cast derviedEventArgs to EventArgs and
//invoke the 'handler' above??????
ilgen.Emit(OpCodes.Pop);
ilgen.Emit(OpCodes.Ret);
Delegate d = dynamic.CreateDelegate(derviedEventHandlerType);
//addMethod is the add MethodInfo for an Event
addMethod.Invoke(target, new object[] { d }); …Run Code Online (Sandbox Code Playgroud) 我试图动态创建一个空构造函数,它接受一个参数,并使用TypeBuilder简单地调用base(参数).
我的代码是这样的:
(...)
// Create a class derived from this class
TypeBuilder typeBuilder = moduleBuilder.DefineType("NewClass", TypeAttributes.Class, this.GetType());
ConstructorInfo baseCtor = this.GetType().GetConstructor(new[] { typeof(int) });
// Define new ctor taking int
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new[] { typeof(int) });
// Generate code to call base ctor passing int
ILGenerator ctorIL = constructorBuilder.GetILGenerator();
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
ctorIL.Emit(OpCodes.Call, baseCtor);
ctorIL.Emit(OpCodes.Ret);
// Generate derived class
Type type = typeBuilder.CreateType();
// Try to instantiate using new constructor
ConstructorInfo ctor = type.GetConstructor(new[] { typeof(int) });
object …Run Code Online (Sandbox Code Playgroud)