Delphi 通用运行时
Delphi generic runtime
我想多次从反序列化中获得泛型 class。
我怎样才能简化它?
我知道 class 我想要什么,但我很懒,不想重复代码。
示例:
procedure Do;
var
cl:tclass1;
cl2:tclass2;
..... N classes;
begin
cl:=tserialization.deserialize<tclass1>(json/xml);
try
DoSmthWithMyClass(cl);
finally
cl.free;
end;
clN:=tserialization.deserialize<tclassN>(json/xml);
try
DoSmthWithMyClass(clN);
finally
clN.free;
end;
end;
如何在循环中反序列化我的 classes?
我知道class我想提前得到什么
已更新:
真实代码及错误:
[dcc32 错误] uMainForm.pas(68): E2250 没有可以使用这些参数
调用的 'Deserialize' 的重载版本
for iSupportClass := Low(TSupportedClasses)
to high(TSupportedClasses) do
begin
if db.GetRef(SupportedClasses[iSupportClass].GetTableName, xml,
error) = 0 then
begin
//here an error
iClass := txmlserializer.Deserialize < SupportedClasses
[iSupportClass] > (xml);
end;
end;
假设所有 classes 都有共同的祖先——在我的例子中是 TQSI2Common)。
type
TSupportedClass = class of TQSI2Common;
TSupportedClasses = ( scQSI2SessionRequest,
scQSI2ErrorReply,
scQSI2SessionRequestReply,
scQSI2LoginRequest,
scQSI2LoginReply,
scQSI2CloseSessionRequest,
scQSI2CloseSessionReply,
scQSI2SiteListRequest,
scQSI2SiteListReply,
scReportCountRequest,
scReportCountReply,
scReportAverageTimeRequest,
scReportAverageTimeReply,
scReportRequest,
scReportReply,
scGetRecsFromKeysRequest,
scGetRecsFromKeysReply );
const
SupportedClasses : array[ TSupportedClasses ] of TSupportedClass = ( TQSI2SessionRequest,
TQSI2ErrorReply,
TQSI2SessionRequestReply,
TQSI2LoginRequest,
TQSI2LoginReply,
TQSI2CloseSessionRequest,
TQSI2CloseSessionReply,
TQSI2SiteListRequest,
TQSI2SiteListReply,
TReportCountRequest,
TReportCountReply,
TReportAverageTimeRequest,
TReportAverageTimeReply,
TReportRequest,
TReportReply,
TGetRecsFromKeysRequest,
TGetRecsFromKeysReply );
然后您可以查看受支持的 SupportedClasses 数组 - 类似于您的情况
procedure Do;
var
iSupportedClass : TSupportedClasses;
iClass : TSupportedClass;
begin
for iSupportedClass := Low( TSupportedClasses) to High(TSupportedClasses)
iClass:=tserialization.deserialize<SupportedClasses[iSupportedClass]>(json/xml);
try
iClass.DoSmthWithMyClass; // this will be an inherited function
finally
iClass.free;
end;
end;
end;
显然这最后一点仅用于说明目的,并未经过测试,但其余部分是实际代码。
编辑
未经测试的代码当然不起作用,因为泛型是编译时而不是 运行 时间操作。
相反,您可以创建一个 class 函数来反序列化,例如:
type
TQSI2Common = class
public
class function Deserialize : TQSI2Common; virtual; abstract;
//...
end;
type
TQSI2Example = class(TQSI2Common)
public
class function Deserialize : TQSI2Common; override;
end;
//....
class function TQSI2Example.Deserialize : TQSI2Common;
begin
Result := tserialization.deserialize<TQSI2Example>(json/xml);
end;
//....
procedure Do;
var
iSupportedClass : TSupportedClasses;
iClass : TSupportedClass;
begin
for iSupportedClass := Low( TSupportedClasses) to High(TSupportedClasses)
iClass:=SupportedClasses[iSupportedClass].Deserialize;
try
iClass.DoSmthWithMyClass; // this will be an inherited function
finally
iClass.free;
end;
end;
end;
编辑2
在您在新问题中提供的上下文中,可以处理泛型,但它变得有点混乱。下面修改后的 class 定义表明:
type
TQSI2Common = class // Note NOT a Generic
public
class function Deserialize : TQSI2Common; virtual; abstract;
//...
end;
type
TQSI2Example<T : class> = class(TQSI2Common) // note IS generic.
public
end;
type TFirms = class( TQSI2Example<TFirm> )
public
class function Deserialize : TQSI2Common; override;
end;
type TDiscounts = class( TRefTable<TDiscount> )
public
class function Deserialize : TQSI2Common; override;
end;
//....
class function TFirms.Deserialize : TQSI2Common; override;
begin
Result := tserialization.deserialize<TFirms>(json/xml);
end;
等等
我想多次从反序列化中获得泛型 class。 我怎样才能简化它?
我知道 class 我想要什么,但我很懒,不想重复代码。
示例:
procedure Do;
var
cl:tclass1;
cl2:tclass2;
..... N classes;
begin
cl:=tserialization.deserialize<tclass1>(json/xml);
try
DoSmthWithMyClass(cl);
finally
cl.free;
end;
clN:=tserialization.deserialize<tclassN>(json/xml);
try
DoSmthWithMyClass(clN);
finally
clN.free;
end;
end;
如何在循环中反序列化我的 classes? 我知道class我想提前得到什么
已更新:
真实代码及错误: [dcc32 错误] uMainForm.pas(68): E2250 没有可以使用这些参数
调用的 'Deserialize' 的重载版本for iSupportClass := Low(TSupportedClasses)
to high(TSupportedClasses) do
begin
if db.GetRef(SupportedClasses[iSupportClass].GetTableName, xml,
error) = 0 then
begin
//here an error
iClass := txmlserializer.Deserialize < SupportedClasses
[iSupportClass] > (xml);
end;
end;
假设所有 classes 都有共同的祖先——在我的例子中是 TQSI2Common)。
type
TSupportedClass = class of TQSI2Common;
TSupportedClasses = ( scQSI2SessionRequest,
scQSI2ErrorReply,
scQSI2SessionRequestReply,
scQSI2LoginRequest,
scQSI2LoginReply,
scQSI2CloseSessionRequest,
scQSI2CloseSessionReply,
scQSI2SiteListRequest,
scQSI2SiteListReply,
scReportCountRequest,
scReportCountReply,
scReportAverageTimeRequest,
scReportAverageTimeReply,
scReportRequest,
scReportReply,
scGetRecsFromKeysRequest,
scGetRecsFromKeysReply );
const
SupportedClasses : array[ TSupportedClasses ] of TSupportedClass = ( TQSI2SessionRequest,
TQSI2ErrorReply,
TQSI2SessionRequestReply,
TQSI2LoginRequest,
TQSI2LoginReply,
TQSI2CloseSessionRequest,
TQSI2CloseSessionReply,
TQSI2SiteListRequest,
TQSI2SiteListReply,
TReportCountRequest,
TReportCountReply,
TReportAverageTimeRequest,
TReportAverageTimeReply,
TReportRequest,
TReportReply,
TGetRecsFromKeysRequest,
TGetRecsFromKeysReply );
然后您可以查看受支持的 SupportedClasses 数组 - 类似于您的情况
procedure Do;
var
iSupportedClass : TSupportedClasses;
iClass : TSupportedClass;
begin
for iSupportedClass := Low( TSupportedClasses) to High(TSupportedClasses)
iClass:=tserialization.deserialize<SupportedClasses[iSupportedClass]>(json/xml);
try
iClass.DoSmthWithMyClass; // this will be an inherited function
finally
iClass.free;
end;
end;
end;
显然这最后一点仅用于说明目的,并未经过测试,但其余部分是实际代码。
编辑
未经测试的代码当然不起作用,因为泛型是编译时而不是 运行 时间操作。
相反,您可以创建一个 class 函数来反序列化,例如:
type
TQSI2Common = class
public
class function Deserialize : TQSI2Common; virtual; abstract;
//...
end;
type
TQSI2Example = class(TQSI2Common)
public
class function Deserialize : TQSI2Common; override;
end;
//....
class function TQSI2Example.Deserialize : TQSI2Common;
begin
Result := tserialization.deserialize<TQSI2Example>(json/xml);
end;
//....
procedure Do;
var
iSupportedClass : TSupportedClasses;
iClass : TSupportedClass;
begin
for iSupportedClass := Low( TSupportedClasses) to High(TSupportedClasses)
iClass:=SupportedClasses[iSupportedClass].Deserialize;
try
iClass.DoSmthWithMyClass; // this will be an inherited function
finally
iClass.free;
end;
end;
end;
编辑2
在您在新问题中提供的上下文中,可以处理泛型,但它变得有点混乱。下面修改后的 class 定义表明:
type
TQSI2Common = class // Note NOT a Generic
public
class function Deserialize : TQSI2Common; virtual; abstract;
//...
end;
type
TQSI2Example<T : class> = class(TQSI2Common) // note IS generic.
public
end;
type TFirms = class( TQSI2Example<TFirm> )
public
class function Deserialize : TQSI2Common; override;
end;
type TDiscounts = class( TRefTable<TDiscount> )
public
class function Deserialize : TQSI2Common; override;
end;
//....
class function TFirms.Deserialize : TQSI2Common; override;
begin
Result := tserialization.deserialize<TFirms>(json/xml);
end;
等等