質問にあまり関係のない理由で、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);
宛先:(私が推測する最も美しい実装ではありません)
手順の新しい変数:
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;
敬具、
ダン