由于问题与问题本身不相关,我想在我的TRemotable类中使用泛型。但我发现Soap.OPToSOAPDomConv.pas存在一些问题。它正在使用旧的RTTI,我猜测无法处理泛型,因此该类未序列化为xml。
我已经成功更改了Soap.OPToSOAPDomConv.pas以便支持泛型。我的主要问题是,在Delphi源文件中进行更改是否被认为是可以接受的? 如果不行,有更好的方式吗?只要我自己使用它,我想没有大问题,但很难将源代码分发给他人,而且还需考虑Delphi未来的变化。 这篇冗长的文章的其余部分只是关于我实际在做什么的细节 :-)
我已更改Soap.OPToSOAPDomConv.pas(第3759行)。
亲切问候,
丹
我已经成功更改了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 Service导入的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;
To:
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;
亲切问候,
丹