如何实现自定义泛型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
相关产品推荐
相关产品推荐

