C# 未调用反序列化构造函数
我正在尝试序列化/反序列化包含C# 未调用反序列化构造函数,c#,.net,serialization,iserializable,C#,.net,Serialization,Iserializable,我正在尝试序列化/反序列化包含字典的对象。这两种都是自定义类型 在我的代码中,我有一种模板,其中包含字典。我正试图序列化/反序列化的是模板类 为了解决这个集合是字典的问题,我在我的模板类上实现了ISerializable接口 [Serializable] public class Template : ISerializable { protected Template(SerializationInfo info, StreamingContext context) {
字典的对象。这两种都是自定义类型
在我的代码中,我有一种模板,其中包含字典
。我正试图序列化/反序列化的是模板类
为了解决这个集合是字典的问题,我在我的模板类上实现了ISerializable
接口
[Serializable]
public class Template : ISerializable
{
protected Template(SerializationInfo info, StreamingContext context)
{
// Deserialize the sections
List<Tuid> tuids = (List<Tuid>)info.GetValue("Sections_Keys", typeof(List<Tuid>));
List<Section> sections = (List<Section>)info.GetValue("Sections_Values", typeof(List<Section>));
this._sections = new Dictionary<Tuid, Section>();
for (int i = 0; i < tuids.Count; i++)
{
_sections.Add(tuids[i], sections[i]);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
List<Tuid> tuids = new List<Tuid>();
List<Section> sections = new List<Section>();
foreach (KeyValuePair<Tuid, Section> kvp in _sections)
{
tuids.Add(kvp.Key);
sections.Add(kvp.Value);
}
info.AddValue("Sections_Keys", tuids, typeof(List<Tuid>));
info.AddValue("Sections_Values", sections, typeof(List<Section>));
}
问题是,当我序列化GetObjectData()
时,我的模板和节都被调用,这使我相信数据是可序列化的,并且它正在被序列化
当我反序列化时,只调用模板上的反序列化构造函数。从未调用节的反序列化构造函数。其结果是对info.GetValue(“Section\u Values”…)
的调用确实返回了一个列表,但其中有一个项,该项为空
为什么我的反序列化节的构造函数从未被调用?是否该节中的某些数据不可序列化?如果是这样的话,如何找出它无法序列化的内容
更新:我刚刚发现的一件事是,节的BaseObject标记为[Serializable]
,但没有实现ISerializable
此外,我想知道反序列化代码有多复杂-它会针对一个同时构造基类的构造函数吗
更新..
好的,我把这个问题追溯到这一节的系列化。代码看起来像这样
protected Section(SerializationInfo info, StreamingContext context):base(.....)
{
// Code
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
//info.AddValue("CustomObject", ClientInfo, typeof(CustomObject));
//info.AddValue("Description", Description, typeof(string));
}
注释掉这两行后,将不序列化任何内容,并在部分
上调用反序列化构造函数。如果我加入字符串值,一切仍然正常。但是,是的-您猜对了-如果我将CustomObject
添加到序列化流中,则不会调用反序列化构造函数
请注意
- 我的
节
的反序列化构造函数是一个空白方法-我不尝试对反序列化的数据执行任何操作
- 节的基本构造函数已经被删除,以便传入新的有效对象,我已经确认这运行正常
- 不会抛出异常来告诉我无法序列化
CustomObject
CustomObject
是可序列化的,其GetObjectData()
方法运行良好,其构造在反序列化时运行良好
似乎很奇怪,如果纯粹是将这个可序列化对象添加到流中,那么框架就无法使用节的反序列化器构造函数
为什么会发生这种情况?其中一个选项是实施
[OnDeserializing]
void OnDeserializing(StreamingContext c)
{
//create what is required here
}
在模板
类中,由于默认的Serriaizer不调用子对象的构造函数-节
类我相信您的问题是因为序列化的工作方式(我似乎记得它是宽度优先,而不是深度优先)。这意味着它将反序列化您的模板,然后在其中创建空间以添加到您的节中
但是,这些部分尚未反序列化,它们将在模板完成反序列化后反序列化。您应该能够通过使用断点并让代码在更远的地方运行来检查这一点。解决这个问题的方法可以是oleksii的解决方案,也可以类似于使用IDeserializationCallback
IDeserializationCallback是什么?当实例完成反序列化(及其成员)后,它将调用一个方法以允许您进行一些连接。我会尝试以下类似的方法:
[Serializable]
public class Template : ISerializable, IDeserializationCallback
{
private List<Tuid> tuids;
private List<Section> sections
protected Template(SerializationInfo info, StreamingContext context)
{
tuids = (List<Tuid>)info.GetValue("Sections_Keys", typeof(List<Tuid>));
sections = (List<Section>)info.GetValue("Sections_Values", typeof(List<Section>));
this._sections = new Dictionary<Tuid, Section>();
}
public void OnDeserialization(object sender)
{
// Section serialization constructor should have been called by this point
for (int i = 0; i < tuids.Count; i++)
{
_sections.Add(tuids[i], sections[i]);
}
}
}
[可序列化]
公共类模板:ISerializable,IDeserializationCallback
{
私人名单;
私人名单部分
受保护的模板(SerializationInfo、StreamingContext上下文)
{
tuids=(List)info.GetValue(“Sections_Keys”,typeof(List));
sections=(List)info.GetValue(“sections_Values”,typeof(List));
这是。_sections=new Dictionary();
}
公共序列化(对象发送方)
{
//此时应调用节序列化构造函数
for(int i=0;i
Ok,看起来是个好主意-如何将我的子对象提取到我的模板类中?此外,反序列化如何知道列表中有1个对象但其为空,这很奇怪。我不太确定,但我假设您可以重用模板
和节
的构造函数中的代码。我认为这更适合于在不希望序列化的类中设置值。例如,如果你有一个计算值,你可以从另外两个值中计算出来。你可以用这个方法来计算。我喜欢你序列化字典的方法:)我不知道这是不是一个好方法:)目前它不起作用,所以不会那么好:)你是如何获得要调用的GetObjectData的?我尝试了一段时间,但这个方法从未被调用
[Serializable]
public class Template : ISerializable, IDeserializationCallback
{
private List<Tuid> tuids;
private List<Section> sections
protected Template(SerializationInfo info, StreamingContext context)
{
tuids = (List<Tuid>)info.GetValue("Sections_Keys", typeof(List<Tuid>));
sections = (List<Section>)info.GetValue("Sections_Values", typeof(List<Section>));
this._sections = new Dictionary<Tuid, Section>();
}
public void OnDeserialization(object sender)
{
// Section serialization constructor should have been called by this point
for (int i = 0; i < tuids.Count; i++)
{
_sections.Add(tuids[i], sections[i]);
}
}
}