如何在未知类型时遍历List<>并递归序列化集合元素?
修复List<>类型属性的递归序列化问题
你的代码存在两个核心问题,导致List类型的属性无法正确遍历元素序列化:
- List类型判断错误:
typeof(List<>)是开放泛型类型,而实际属性的类型是封闭泛型(比如List<int>),直接用==判断永远不成立。 - WriteCollectionPropertyToWriter逻辑完全错误:你现在是在遍历
PropertyInfo自身的属性,而不是获取列表中的元素进行序列化。
修改后的完整代码
public class NetworkPacketSerializer { public static IEnumerable<byte> SerializeToBytes(object packet) { var writer = new NetworkPacketWriter(); var properties = packet.GetType().GetProperties(); var identifierAttribute = packet.GetType().GetCustomAttribute<PacketIdAttribute>(); if (identifierAttribute == null) { throw new InvalidOperationException($"Missing packet identifier attribute for packet type {packet.GetType()}"); } writer.WriteShort(identifierAttribute.I); foreach (var property in properties) { // 只处理带PacketDataAttribute的属性,匹配原代码过滤逻辑 if (Attribute.IsDefined(property, typeof(PacketDataAttribute))) { WriteProperty(property, writer, packet); } } return writer.GetAllBytes(); } private static void WriteCollectionPropertyToWriter(PropertyInfo propertyInfo, NetworkPacketWriter writer, object packet) { // 获取列表的实际实例 var list = propertyInfo.GetValue(packet) as IEnumerable; if (list == null) return; // 先写入列表长度,方便反序列化时读取 writer.WriteInteger(list.Cast<object>().Count()); // 遍历列表中的每个元素 foreach (var item in list) { if (item == null) continue; var itemType = item.GetType(); // 基础类型/字符串直接调用对应写入方法 if (itemType == typeof(string)) { writer.WriteString((string)item); } else if (itemType == typeof(int)) { writer.WriteInteger((int)item); } else if (itemType == typeof(short)) { writer.WriteShort((short)item); } // 自定义类则递归序列化其属性 else { foreach (var prop in itemType.GetProperties().Where(p => Attribute.IsDefined(p, typeof(PacketDataAttribute)))) { WriteProperty(prop, writer, item); } } } } private static void WriteProperty(PropertyInfo property, NetworkPacketWriter writer, object packet) { var propertyType = property.PropertyType; var value = property.GetValue(packet); if (value == null) return; if (propertyType == typeof(string)) { writer.WriteString((string)value); } else if (propertyType == typeof(int)) { writer.WriteInteger((int)value); } else if (propertyType == typeof(short)) { writer.WriteShort((short)value); } // 正确识别所有List<T>泛型类型 else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>)) { WriteCollectionPropertyToWriter(property, writer, packet); } // 可按需扩展其他类型的处理逻辑 } }
关键修改说明
- 修正List类型判断:通过
IsGenericType结合GetGenericTypeDefinition(),准确识别所有List<T>封闭泛型类型。 - 重构集合处理逻辑:先获取列表实例,写入列表长度(反序列化时必须的标记),再逐个遍历元素,根据元素类型选择直接写入或递归序列化属性。
- 统一属性过滤:在根序列化方法中只处理带
PacketDataAttribute的属性,避免序列化无关字段。
内容的提问来源于stack exchange,提问作者user5405648
相关产品推荐
相关产品推荐

