未调用反序列化构造函数

Rem*_*tec 11 .net c# serialization iserializable

我试图序列化/反序列化包含a的对象Dictionary<Tuid,Section>.这些都是自定义类型.

在我的代码中,我有一种模板,其中包含Dictionary<Tuid,Section>.我试图序列化/反序列化的是Template类.

要解决此集合是字典的问题,我已ISerializable在Template类上实现了接口....

[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>));
   }
Run Code Online (Sandbox Code Playgroud)

这里的策略是将字典"解包"成两个单独的列表,并将它们单独存储在序列化流中.然后他们会在之后重新创建.

我的课也是ISerializable...

[Serializable]
public class Section : BaseObject
{

    protected Section(SerializationInfo info, StreamingContext context):base(.....)
    {
        // Code
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
       // code
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是当我GetObjectData()在我的模板我的部分上调用序列化时,这让我相信数据是Serializable并且它被序列化了.

当我反序列化时,调用Template上的反序列化构造函数.从不调用Section的反序列化构造函数.结果是调用info.GetValue("Section_Values"....) 确实返回一个List,但它有一个项目,该项目为null.

为什么我的构造函数反序列化一个段永远不会被调用?可能是该部分内的一些数据不可序列化?如果是这样,如何找出它无法序列化的确切内容?

更新:我刚刚发现的一件事是BaseObject for section被标记[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));
}
Run Code Online (Sandbox Code Playgroud)

有了这两个注释掉的线条,没有什么是序列化和反序列化构造函数被调用的Section.如果我添加字符串值,一切都还可以.但是,是的 - 您猜对了 - 如果我将CustomObject序列化流添加到序列化流中,则不会调用反序列化构造函数.

注意...

  • 我的反序列化构造函数Section是一个空白的方法 - 我不会尝试对反序列化的数据做任何事情.
  • Section的基本构造函数已经被删除以传入新的有效对象,我已经确认它运行正常.
  • 没有异常告诉我CustomObject无法序列化.
  • CustomObject是可序列化和其GetObjectData()方法运行良好和反序列化上其构造细.

奇怪的是,纯粹将这个可序列化的对象添加到流中,然后框架才会失败到反序列化构造函数Section!!

为什么会发生这种情况?

ole*_*sii 12

其中一个选择是实施

[OnDeserializing]
void OnDeserializing(StreamingContext c)
{
    //create what is required here
}
Run Code Online (Sandbox Code Playgroud)

Template类中,因为默认的serrializer不会调用子对象的构造函数 - Section

  • 我*认为*这更倾向于在您不想序列化的类中设置值.例如,如果您有一个计算值,您可以从其他两个值中计算出来.你可以用这种方法计算它. (2认同)