我有一组文件,其中包含来自第三方 dll 的类的二进制序列化实例。我无权访问第三方源代码,但我有 dll。我需要将这些文件反序列化为类的实例。
我只是这样做:
Stream stream = File.Open(@"C:\my\path", FileMode.Open);
BinaryFormatter binaryFormatter = new BinaryFormatter();
ThirdPartyType o = binaryFormatter.Deserialize(stream) as ThirdPartyType;
stream.Close();
这没有错误。当我在调试模式下运行项目并在反序列化后放置断点时,我可以检查实例o
。的所有成员o
都创建了实例null
,0
但没有成员被初始化为正确的值。
我尝试反编译 dll(使用 .Net Reflector)并在以下位置插入断点:
protected ThirdPartyType(SerializationInfo info, StreamingContext context) {}
现在我可以检查参数info
,在这里我可以看到成员m_types
, m_members
&m_data
被设置为我期望从序列化文件中获得的正确值。但是,由于某种原因,构造函数不会使用它并正确初始化实例。我只能看到这个构造函数头,反编译不会显示它的代码。
为了自己控制初始化,我创建了该类的本地子类:
[Serializable]
public class FakeThirdPartyType : ThirdPartyType
{
protected FakeThirdPartyType(SerializationInfo info, StreamingContext context) : base(info, context)
{
int width = info.GetInt32("clientWidth");
this.ClientWidth = width;
//Many other properties as well...
}
}
然后我将 my 绑定BinaryFormatter
到请求时SerializationBinder
返回的 a (以及任何其他调用的正确类型)。现在,当我运行它时,我得到了我的反序列化构造函数。但在这里我有一个非常奇怪的问题。我可以看到它被分配了正确的值(),但在下一行之后仍然是. 与以下结果相同:FakeThirdPartyType
ThirdPartyType
width
!=0
this.ClientWidth
0
base.GetType().GetProperty("ClientWidth").SetValue(this, width, null);
可能有什么我做错了吗?我遇到的问题可能是由交叉汇编反序列化引起的吗?错误是否可能在于我无法访问的第三方代码?似乎属性的设置器不起作用(至少不影响与 getter 返回相同的变量)。
在调试期间,我可以检查ThirdPartyType
类型并查看它是否具有私有字段_clientWidth
,但我找不到任何直接设置它的方法。