You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现自定义泛型List的序列化?重点解决GetObjectData方法

回答

要实现GetObjectData方法,核心是把你的自定义列表的状态数据写入SerializationInfo对象,这样反序列化时才能重建出完全一致的列表。下面是具体的实现步骤和注意事项:

1. 先确保类和依赖类型可序列化

首先,你的Liste<T>和内部的List_Element<T>都需要标记[Serializable]特性(实现ISerializable的类必须显式标记这个特性),同时泛型参数T对应的类型也必须是可序列化的(比如自定义类要加[Serializable],或者实现ISerializable)。

[Serializable]
class Liste<T> : IEnumerable, ISerializable 
{
    // 你的现有代码...
}

[Serializable]
class List_Element<T>
{
    public T Data { get; set; }
    public List_Element<T> Next { get; set; }
    public List_Element<T> Prev { get; set; }
}

2. 实现GetObjectData方法

对于你的双向链表结构,需要序列化的关键数据是所有元素的Data值和Count(Count可以从元素数量推导,但提前存储能让反序列化更高效)。你可以直接遍历链表(比依赖IEnumerable更可靠,因为你的GetEnumerator逻辑可能存在小问题):

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    // 先存储元素总数,方便反序列化时循环读取
    info.AddValue("Count", Count);
    
    // 从链表头开始遍历所有元素,逐个存入SerializationInfo
    List_Element<T> currentNode = First;
    int elementIndex = 0;
    while (currentNode != null)
    {
        // 用带索引的键名(比如"Element0")确保每个元素有唯一标识
        info.AddValue($"Element{elementIndex}", currentNode.Data);
        currentNode = currentNode.Next;
        elementIndex++;
    }
}

关于foreach的疑问

你当然可以用foreach,但要注意你的GetEnumerator返回的是List_Element<T>类型,而不是T,所以foreach时需要取Data属性:

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    info.AddValue("Count", Count);
    int elementIndex = 0;
    foreach (List_Element<T> node in this)
    {
        info.AddValue($"Element{elementIndex}", node.Data);
        elementIndex++;
    }
}

不过直接遍历链表的方式更直接,不需要依赖GetEnumerator的正确性,推荐用第一种写法。

3. 必须添加反序列化构造函数

实现ISerializable的类必须提供一个受保护的反序列化构造函数,否则反序列化时会抛出异常。这个构造函数要读取GetObjectData写入的数据,重建链表:

protected Liste(SerializationInfo info, StreamingContext context)
{
    // 先读取元素总数
    int count = info.GetInt32("Count");
    Count = count;
    First = null;
    Last = null;

    // 逐个读取元素,用你已有的Add方法添加到新列表中
    for (int i = 0; i < count; i++)
    {
        T element = (T)info.GetValue($"Element{i}", typeof(T));
        Add(element);
    }
}

关键说明

  • 为什么不序列化链表节点本身?因为节点的Next和Prev引用是内存地址,序列化这些引用没有意义,反序列化时内存地址已经变化,所以只需要序列化元素的实际数据,然后重新构建链表即可。
  • 如果T是自定义类,比如你注释里的Person,一定要给Person类添加[Serializable]特性,否则会序列化失败。

内容的提问来源于stack exchange,提问作者Blopsrusher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:37:22