"操作可能destablize运行"和DynamicMethod的值类型 [英] "Operation could destablize the runtime" and DynamicMethod with value types

查看:335
本文介绍了"操作可能destablize运行"和DynamicMethod的值类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着概括如下IL(从反射镜):

 。方法私人hidebysig实例无效的SetValue(值类型Test.TestFixture / ValueSource和放大器;件事,字符串'值')CIL管理
{
.maxstack 8
L_0000:NOP
L_0001:ldarg.1
L_0002:ldarg 0.2
L_0003:呼叫实例无效Test.TestFixture / ValueSource :: SET_VALUE(字符串)
L_0008:NOP
L_0009:RET
}

然而,当我试着和DynamicMethod的重现此IL:

  [测试] 
公共无效Test_with_DynamicMethod()
{
VAR sourceType的= typeof运算(ValueSource);
的PropertyInfo财产= sourceType.GetProperty(值);

VAR二传手= property.GetSetMethod(真);
VAR方法=新的DynamicMethod的(设置+ property.Name,空,新的[] {sourceType.MakeByRefType(),typeof运算(字符串)},真);
无功根= method.GetILGenerator();

gen.Emit(OpCodes.Ldarg_1); //加载输入堆放
gen.Emit(OpCodes.Ldarg_2); //将值堆栈
gen.Emit(OpCodes.Call,二传手); //调用setter方法
gen.Emit(OpCodes.Ret);

VAR的结果=(SetValueDelegate)method.CreateDelegate(typeof运算(SetValueDelegate));

无功源=新ValueSource();

结果(参考源,你好);

source.Value.ShouldEqual(你好);
}

公众委托无效SetValueDelegate(REF ValueSource源,字符串值);



我得到的操作可能会破坏运行时异常。该IL似乎等同于我来说,任何想法? ValueSource是值类型,这就是为什么我在这里做一个参考参数。



修改



这里的ValueSource类型:

 公共结构ValueSource 
{
公共字符串值{搞定;组; }
}


解决方案

更改args设置为0 / 1(不1/2):

  gen.Emit(OpCodes.Ldarg_0); //加载输入堆放
gen.Emit(OpCodes.Ldarg_1); //将值堆栈



,因为它似乎动态方法为静态的,不是实例创建(你原来的方法是实例) - 因此ARG游戏关闭由一个



(对不起,原来错误的答案 - 你可以离开的代码与其它位为真正


I'm trying to generalize the following IL (from Reflector):

.method private hidebysig instance void SetValue(valuetype Test.TestFixture/ValueSource& thing, string 'value') cil managed
{
    .maxstack 8
    L_0000: nop 
    L_0001: ldarg.1 
    L_0002: ldarg.2 
    L_0003: call instance void Test.TestFixture/ValueSource::set_Value(string)
    L_0008: nop 
    L_0009: ret 
}

However, when I try and reproduce this IL with DynamicMethod:

    	[Test]
	public void Test_with_DynamicMethod()
	{
		var sourceType = typeof(ValueSource);
		PropertyInfo property = sourceType.GetProperty("Value");

		var setter = property.GetSetMethod(true);
		var method = new DynamicMethod("Set" + property.Name, null, new[] { sourceType.MakeByRefType(), typeof(string) }, true);
		var gen = method.GetILGenerator();

		gen.Emit(OpCodes.Ldarg_1); // Load input to stack
		gen.Emit(OpCodes.Ldarg_2); // Load value to stack
		gen.Emit(OpCodes.Call, setter); // Call the setter method
		gen.Emit(OpCodes.Ret);

		var result = (SetValueDelegate)method.CreateDelegate(typeof(SetValueDelegate));

		var source = new ValueSource();

		result(ref source, "hello");

		source.Value.ShouldEqual("hello");
	}

	public delegate void SetValueDelegate(ref ValueSource source, string value);

I get an exception of "Operation could destabilize the runtime". The IL seems identical to me, any ideas? ValueSource is a value type, which is why I'm doing a ref parameter here.

EDIT

Here's the ValueSource type:

    	public struct ValueSource
	{
		public string Value { get; set; }
	}

解决方案

Change the args to 0/1 (not 1/2):

    gen.Emit(OpCodes.Ldarg_0); // Load input to stack
    gen.Emit(OpCodes.Ldarg_1); // Load value to stack

because the dynamic method it seems to be created as static, not instance (your original method is instance) - hence the args are off by one.

(sorry for the original wrong answer - you can leave the other bit of code as true)

这篇关于"操作可能destablize运行"和DynamicMethod的值类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆