gpt4 book ai didi

TRemotable 类中的 Delphi XE2 泛型

转载 作者:行者123 更新时间:2023-12-03 15:58:19 25 4
gpt4 key购买 nike

由于与问题无关的原因,我想在我的 TRemotable 类中使用泛型。我发现 Soap.OPToSOAPDomConv.pas 在这方面有一些问题。它使用旧的 RTTI,我猜它不能处理泛型,所以类没有序列化为 xml。

我已经设法更改 Soap.OPToSOAPDomConv.pas 以便它可以与泛型一起使用。我的主要问题是是否认为可以在 Delphi 源文件中进行更改?如果不是,是否有更好的方法来做到这一点?只要只有我一个人在用,我想应该没什么大问题,但很难将源代码分发给其他人,而且还要考虑 Delphi future 的变化。这篇冗长的帖子的其余部分只是关于我实际在做什么的细节:-)

我在 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);

致:(我猜这不是最漂亮的实现)

过程中的新变量:

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 Importer 使所有这些类在 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;

亲切的问候,

最佳答案

进行此类修改时需要考虑两件事。首先,变更是否会对现有功能产生影响。在这种情况下,我会说它是安全的,因为该功能是这个操作的新功能,所以不应该有任何意外行为。第二部分是进化开发环境。环境进化的问题在于, Action 之间的绑定(bind)可能会发生变化,这可能会导致意想不到的事情。现在可以假设 XE2 已经有了它的更新份额。如果不是,则在修补或更新时必须留意。第二种变化,比如从 XE2 到 XE3 的变化,可以更好地处理。只需将以下内容放在 Soap.OPToSOAPDomConv.pas 的顶部:

{$IFNDEF VER230}
{$MESSAGE ERROR 'Intended to be used with XE2'}
{$ENDIF}

当编译出错时,你可能会模糊地记得那个文件有一些东西......所以简而言之,尝试评估影响并适应环境变化并不是坏事。希望这就是您想知道的。

关于TRemotable 类中的 Delphi XE2 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13181842/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com