Delphi通用运行时

时间:2017-07-05 07:54:29

标签: delphi generics runtime deserialization

我想从反序列化中获得泛型类很多次。 我该如何简化它?

我知道我想要哪些课程,但我很懒,不想复制代码。

样品:

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;

如何在循环中反序列化我的类? 我知道我想提前上课的课程

更新:

真实代码和错误: [dcc32错误] uMainForm.pas(68):E2250没有重复版本的&#39;反序列化&#39;可以用这些参数调用

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;

1 个答案:

答案 0 :(得分:0)

这是我如何做一些非常相似的事情,假设所有类都有共同的祖先 - 在我的情况下是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;

显然,最后一点仅用于说明目的而未经过测试,但其余部分是实际代码。

修改

未经测试的代码当然不起作用,因为泛型是编译时而不是运行时操作。

相反,您可以创建一个反序列化的类函数,例如:

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;

EDIT2

在您在新问题中提供的上下文中,可以处理泛型,但它会变得有点混乱。下面修改后的类定义显示了:

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;