下面的代码生成一个异常,表示它可能会使运行时降级。
var method = new DynamicMethod("CallObjectToString", typeof(string),new[]{ typeof(object)});
var ilgen =method.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Call, typeof(object).GetMethod("ToString"));
ilgen.Emit(OpCodes.Ret);
var @delegate = method.CreateDelegate(typeof(Func<object, string>)) as Func<object,string>;
@delegate(new object());
更改
Opcodes.Call
至操作码.CallVirt解决了问题。
这一切都很好,但我可以使用typebuilder创建一个动态类型,该类型具有使用(MethodBuilder)生成的静态方法,该方法具有
确切地
相同的IL,然后使用CreateDelegate,它不会引发此异常。实际上,使用methodbuilder,您可以对完全不同的对象的虚拟方法进行调用,而不是类型继承的方法。
如果我做了这样的事
new object().ToString()
它还发出
call
向IL发出指令,而不是
callvirt
.
如果使用
除了在实例重写中调用基方法的上下文之外,那么为什么CLR允许在不同类型上静态生成这样的方法呢?或允许
呼叫
针对已知的非空实体发出的指令?
或者这仅仅是通过
DynamicMethod
?
编辑:
不稳定作用
var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("SomeAssembly"), AssemblyBuilderAccess.Run) ;
var moduleBuilder = assemblyBuilder.DefineDynamicModule("SomeModule");
var typeBuilder = moduleBuilder.DefineType("SomeType");
var methodBuilder = typeBuilder.DefineMethod("SomeStaticMethod",MethodAttributes.Public | MethodAttributes.Static,typeof(string),new[]{typeof(object)});
var ilgen = methodBuilder.GetILGenerator();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Call, typeof(object).GetMethod("ToString"));
ilgen.Emit(OpCodes.Ret);
var newType = typeBuilder.CreateType();
var @delegate = Delegate.CreateDelegate(typeof(Func<object, string>),newType.GetMethod("SomeStaticMethod")) as Func<object,string>;
@delegate(new object());