“操作可能会破坏运行时的稳定性” 和具有值类型的 DynamicMethod
我正在尝试概括以下 IL(来自 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
}
但是,当我尝试使用 DynamicMethod 重现此 IL 时:
[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);
我收到“操作可能会破坏运行时稳定性”的异常。 IL 对我来说似乎相同,有什么想法吗? ValueSource 是一个值类型,这就是我在这里做一个 ref 参数的原因。
编辑
这是 ValueSource 类型:
public struct ValueSource
{
public string Value { get; set; }
}
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; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将 args 更改为 0/1 (不是 1/2):
因为动态方法似乎被创建为静态方法,而不是实例(您的原始方法是实例) - 因此 args 减少了 1。
(对于最初的错误答案感到抱歉 - 您可以将另一段代码保留为
true
)Change the args to 0/1 (not 1/2):
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
)