由于与我想在我的 TRemotable 类中使用泛型的问题不相关的原因。我发现 Soap.OPToSOAPDomConv.pas 有一些问题。它使用的是旧的 RTTI,我猜它无法处理泛型,因此类不会序列化为 xml。
我设法更改了 Soap.OPToSOAPDomConv.pas 以便它与泛型一起使用。我的主要问题是是否可以对 Delphi 源文件进行更改?如果不是,有没有更好的方法来做到这一点?只要是我自己用的,我想应该没有什么大问题,但是很难把源码分发给其他人,还有Delphi未来的变化需要考虑。这篇冗长的帖子的其余部分只是关于我实际在做什么的细节:-)
我在 Soap.OPToSOAPDomConv.pas 中改变了这个(第 3759 行)
if SerializeProps then
begin
{ Serialized published properties }
Count := GetTypeData(Instance.ClassInfo)^.PropCount;
if Count > 0 then
begin
CheckedElemURI := False;
GetMem(PropList, Count * SizeOf(Pointer));
try
GetPropInfos(Instance.ClassInfo, PropList);
To:(我猜这不是最漂亮的实现)
过程中的新变量:
Context: TRttiContext;
RttiProperty: TRttiProperty;
第 3759 行:
if SerializeProps then
begin
{ Serialized published properties }
Count := 0;
for RttiProperty in Context.GetType(Instance.ClassInfo).GetProperties do
begin
if RttiProperty.Visibility = mvPublished then //The old method only read published
Count := Count + 1; //RTTI scoping [mvPublished] requires changes to
end; //soap.InvRegistry
begin
CheckedElemURI := False;
GetMem(PropList, Count * SizeOf(Pointer));
try
I := 0;
for RttiProperty in Context.GetType(Instance.ClassInfo).GetProperties do
if RttiProperty.Visibility = mvPublished then
begin
PropList[I] := TRttiInstanceProperty(RttiProperty).PropInfo;
I := I + 1;
end;
关于我在做什么的一些细节可能会有所帮助。背景是从 SOAP Web 服务导入的 wsdl 生成了一个巨大的单元,它由大约 2000 个类和 300k 行代码组成。Web 服务设计是我无法控制的。WSDL 导入器使所有这些类在 RTTI 中可见,这会消耗 RTTI 空间并且单元不会编译。
我已经在这里和那里重构了代码,现在有了一个有效的实现。在重构时,我发现我可以通过使用泛型删除大约 50000 行冗余代码。由于 Delphi 无论如何都不会“按原样”编译导入的 wsdl,所以每当 Web 服务中出现新方法时,我都必须手动维护该单元,所以我想让它尽可能可读。
基本上我是根据下面的变化。该示例具有非常简化的类,并且该示例实际上在重构代码中具有更多行,但考虑到原始类有很多程序等,这种方法确实使单元更具可读性,并且也更容易组合类。
TLCar = class(TRemotable)
private
FEngine: string;
FName: string;
published
property Name: string read FName write FName;
property Engine: string read FEngine write FEngine;
end;
TLBicycle = class(TRemotable)
private
FPedals: string;
FName: string;
published
property Name: string read FName write FName;
property Pedals: string read FPedals write FPedals;
end;
TListCarRequest = class(TRemotable)
private
FreturnedTags: TLCar;
published
property returnedTags: TLCar read FreturnedTags write FreturnedTags;
end;
TListBiCycleRequest = class(TRemotable)
private
FreturnedTags: TLBicycle;
published
property returnedTags: TLBicycle read FreturnedTags write FreturnedTags;
到:
TCommonReturnedTags = class(TRemotable)
private
FName: string;
published
property Name: string read FName write FName;
end;
TLCar = class(TCommonReturnedTags)
private
FEngine: string;
published
property Engine: string read FEngine write FEngine;
end;
TLBicycle = class(TCommonReturnedTags)
private
FPedals: string;
published
property Pedals: string read FPedals write FPedals;
end;
TGenericListRequest<T: TCommonReturnedTags, constructor> = class(TRemotable)
private
FreturnedTags: T;
published
property returnedTags: T read FreturnedTags write FreturnedTags;
end;
TListCarRequest = class(TGenericListRequest<TLCar>)
end;
TListBiCycleRequest = class(TGenericListRequest<TLBicycle>)
end;
亲切的问候,
担