我正在尝试将静态初始化程序从一个 DLL 复制到另一个。
如果你在 C# 中有一个静态数组初始值设定项,你会得到如下内容:
.class private auto ansi <PrivateImplementationDetails>{0D3E8B0E-F218-435F-989D-9D04F550A786}
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
.field assembly static valuetype <PrivateImplementationDetails>{0D3E8B0E-F218-435F-989D-9D04F550A786}/__StaticArrayInitTypeSize=120 $$method0x6000060-1 = ((binary data))
我找到了读取这些数据的最简单方法来使用它:
int size = field.FieldType.StructLayoutAttribute.Size;
byte[] data = new byte[size];
RuntimeHelpers.InitializeArray(data, field.FieldHandle);
基本上这会给你上面提到的“二进制数据”。
问题1Dictionary
: 's会发生什么?这仍然有效吗?我很难弄清楚这里到底发生了什么(它似乎被反编译隐藏了)......
我已经发现在实现细节中使用的 GUID 是ModuleBuilder
. 使用其他显式字段信息意味着您应该能够复制数据。
问题 2:如何将数据写回另一个ModuleBuilder
/FieldBuilder
使用 Reflection.Emit?
--
版本?.NET 4.5(VS2013 默认)
似乎对Dictionary
弹出的 's 感到困惑。我在我的代码中进行了一些挖掘,它们似乎作为 [string->int] 字典弹出,用于解析 switch/case 语句。
例如,可以在 mscorlib.dll v4.0.30319.18444 中找到它们。在 Reflector 中,它们看起来像这样:
.field assembly static class System.Collections.Generic.Dictionary`2<string, int32> $$method0x6003a20-1
至于原因:我在对它们执行一些测试之前更改了 DLL。具有讽刺意味的是,我想要这个的原因是因为我不想弄乱实现细节:-) 并且因为多个实例可能会带来麻烦。
换句话说,我基本上只想将它们全部复制“就好像它们是二进制 blob”,如果它们有这样的花哨数据,不管类型等如何,同时保留名称。由于 IL 和数据在不同的 DLL 中以相同的方式处理,因此无论编译器恕我直言,这总是可能的,对吧?