gpt4 book ai didi

c# - 如何使用 IL 改变盒装结构

转载 作者:IT王子 更新时间:2023-10-29 04:19:21 24 4
gpt4 key购买 nike

假设我们有一个可变的 struct(是的,不要开始):

public struct MutableStruct
{
public int Foo { get; set; }
public override string ToString()
{
return Foo.ToString();
}
}

使用反射,我们可以获取此 struct 的盒装实例并在盒内改变它:

// this is basically what we want to emulate
object obj = new MutableStruct { Foo = 123 };
obj.GetType().GetProperty("Foo").SetValue(obj, 456);
System.Console.WriteLine(obj); // "456"

喜欢 做的是编写一些 IL,它可以做同样的事情——但速度更快。我是元编程迷;p

取消装箱任何值并使用常规 IL 改变值是微不足道的 - 但您不能在之后调用它,因为这将创建一个不同的框。我猜测我们在这里需要做的是将它复制到现有框上。我已经调查了 ldobj/stobj,但那些似乎并没有完成这项工作(除非我遗漏了什么)。

那么:是否存在执行此操作的机制?还是我必须将自己限制在反射上以执行盒装 struct 的就地更新?

或者换句话说:什么...邪恶在这里......

var method = new DynamicMethod("evil", null,
new[] { typeof(object), typeof(object) });
var il = method.GetILGenerator();
// ... evil goes here...
il.Emit(OpCodes.Ret);

Action<object, object> action = (Action<object, object>)
method.CreateDelegate(typeof(Action<object, object>));
action(obj, 789);
System.Console.WriteLine(obj); // "789"

最佳答案

嗯,那很有趣。

使用 LdfldaStind_* 似乎可行。 实际上,它主要是 Unbox(请参阅 history for version that works with Ldflda and Stind_*)。

这是我在 LinqPad 中一起破解的内容以证明这一点。

public struct MutableStruct
{
public int Foo { get; set; }

public override string ToString()
{
return Foo.ToString();
}
}

void Main()
{
var foo = typeof(MutableStruct).GetProperty("Foo");
var setFoo = foo.SetMethod;

var dynMtd = new DynamicMethod("Evil", typeof(void), new [] { typeof(object), typeof(int) });
var il = dynMtd.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // object
il.Emit(OpCodes.Unbox, typeof(MutableStruct)); // MutableStruct&
il.Emit(OpCodes.Ldarg_1); // MutableStruct& int
il.Emit(OpCodes.Call, setFoo); // --empty--
il.Emit(OpCodes.Ret); // --empty--

var del = (Action<object, int>)dynMtd.CreateDelegate(typeof(Action<object, int>));

var mut = new MutableStruct { Foo = 123 };

var boxed= (object)mut;

del(boxed, 456);

var unboxed = (MutableStruct)boxed;
// unboxed.Foo = 456, mut.Foo = 123
}

关于c# - 如何使用 IL 改变盒装结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18937935/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com