如何在Delphi的TListHelper<T>中实现TILObject的序列化与反序列化
修改泛型
TListHelper<T>以支持TILObject类型的序列化与反序列化 核心思路是通过运行时类型判断区分值类型(如Integer)与TILObject子类,分别执行对应逻辑:对于TILObject实例,直接调用其自身的Serialize/Deserialize方法;对于Integer则保留原有实现。
修改后的TListHelper<T>核心方法代码
procedure TListHelper<T>.Serialize(AStream: TStream; AList: TList<T>); var I: Integer; LItem: T; LObj: TILObject; begin // 先写入集合元素总数 AStream.WriteBuffer(AList.Count, SizeOf(Integer)); for I := 0 to AList.Count - 1 do begin LItem := AList[I]; // 判断当前类型是否为TILObject子类 if GetTypeKind(T) = tkClass and (LItem is TILObject) then begin LObj := TILObject(LItem); LObj.Serialize(AStream); end // 保留原Integer类型处理逻辑 else if GetTypeKind(T) = tkInteger then begin AStream.WriteBuffer(LItem, SizeOf(Integer)); end else raise Exception.CreateFmt('不支持序列化的类型:%s', [TypeName(T)]); end; end; procedure TListHelper<T>.Deserialize(AStream: TStream; out AList: TList<T>); var LCount: Integer; I: Integer; LItem: T; LObj: TILObject; begin AList := TList<T>.Create; try // 先读取集合元素总数 AStream.ReadBuffer(LCount, SizeOf(Integer)); for I := 0 to LCount - 1 do begin // 判断当前类型是否继承自TILObject if GetTypeKind(T) = tkClass and (TClass(T).InheritsFrom(TILObject)) then begin // 创建TILObject子类实例(要求类有无参构造函数) LObj := TClass(T).Create as TILObject; try LObj.Deserialize(AStream); AList.Add(T(LObj)); except LObj.Free; raise; end; end // 保留原Integer类型处理逻辑 else if GetTypeKind(T) = tkInteger then begin AStream.ReadBuffer(LItem, SizeOf(Integer)); AList.Add(LItem); end else raise Exception.CreateFmt('不支持反序列化的类型:%s', [TypeName(T)]); end; except AList.Free; raise; end; end;
关键注意事项
- 类型兼容性:
- 若要严格限制
T为TILObject子类,可在类定义时添加类型约束:TListHelper<T> = class(TInterfacedObject, IListHelper<T>) where T: class, TILObject;,但这样会失去对Integer等值类型的支持,需根据业务场景选择。
- 若要严格限制
- 实例创建要求:
- 反序列化
TILObject子类时,要求目标类必须提供无参构造函数;若子类需要带参构造,需扩展ILObject接口添加CreateInstance方法,或通过RTTI动态调用带参构造。
- 反序列化
- 内存安全:
- 反序列化过程中若创建实例失败,代码会自动释放已创建的对象并重新抛出异常,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Sdean
相关产品推荐
相关产品推荐

