为通过元类实例化的实例序列化JSON对象 [英] Serializing JSON object for an instance instantiated through a metaclass
问题描述
SuperObject库有一个序列化对象的通用方法:
类型
TSomeObject = class
...
end;
var
lJSON:ISuperObject;
lContext:TSuperRttiContext;
lSomeObject:TSomeObject;
begin
lSomeObject:= TSomeObject.Create;
lContext:= TSuperRttiContext.Create;
lJSON:= lContext.AsJson< TSomeObject>(lSomeObject);
但现在我正在处理元类实例。
这是对象结构:
TJSONStructure = class(TObject);
TReqBase = class(TJSONStructure)
private
token:Int64;
public
end;
TReqLogin = class(TReqBase)
private
username,
password:String;
module:Integer;
public
end;
类型
TWebAct =(ttlogin,
ttsignin);
TReqClass = TReqBase类;
const
cWebActStructures:数组[TWebAct]的
记录
RequestClass:TReqClass;
end
=(
{ttlogin}(RequestClass:TReqLogin;),
{ttsignin}(RequestClass:TReqSignIn;)//不在
以上的定义);
如果我现在尝试:
var
lContext:TSuperRttiContext;
lJSON:ISuperObject;
lRequestClass:TReqClass;
lRequestBase:TReqBase;
begin
lRequestClass:= cWebActStructures [ttlogin] .RequestClass;
lRequestBase:= lRequestClass.Create; // TReqLogin类型的实例
lContext:= TSuperRttiContext.Create;
lJSON:= lContext.AsJson< TReqBase>(lRequestBase);
我得到序列化的TReqBase: lJSON.AsString ='{token :-12346789}'
我想让TReqLogin序列化。
试过:
-
lContext.AsJson< TReqLogin>(lRequestBase);将不起作用:不兼容的类型)[此外,我将不得不在我的例程中列出/处理所有可能的RequestClass类型]
lRequestBase.ClassType>(lRequestBase)都不是:E2531方法'AsJson'需要显式类型参数
任何方式我可以让我的lRequestBase序列化为TReqLogin,TReq ...而不必为它们全部编码?
诀窍是不是创建一个 TSuperRttiContext
并自己调用它的AsJSOn方法,但要立即使用:
lJSON:= RequestBase.ToJSON;
然后,ToJSON方法将在幕后创建一个TSuperRttiContext并处理必要的转换。
非常感谢 Marjan 的帮助。
The SuperObject library has a generic method for serializing objects:
type
TSomeObject = class
...
end;
var
lJSON : ISuperObject;
lContext : TSuperRttiContext;
lSomeObject : TSomeObject;
begin
lSomeObject := TSomeObject.Create;
lContext := TSuperRttiContext.Create;
lJSON := lContext.AsJson<TSomeObject>(lSomeObject);
But now I'm dealing with metaclass instances.
This is the object structure:
TJSONStructure = class(TObject);
TReqBase = class(TJSONStructure)
private
token: Int64;
public
end;
TReqLogin = class(TReqBase)
private
username,
password: String;
module : Integer;
public
end;
type
TWebAct = (ttlogin,
ttsignin);
TReqClass = class of TReqBase;
const
cWebActStructures: Array[TWebAct] of
record
RequestClass : TReqClass;
end
= (
{ ttlogin } (RequestClass: TReqLogin;),
{ ttsignin } (RequestClass: TReqSignIn;) // Not in definitions above
);
If I now try:
var
lContext : TSuperRttiContext;
lJSON : ISuperObject;
lRequestClass : TReqClass;
lRequestBase : TReqBase;
begin
lRequestClass := cWebActStructures[ttlogin].RequestClass;
lRequestBase := lRequestClass.Create; // instance of type TReqLogin
lContext := TSuperRttiContext.Create;
lJSON := lContext.AsJson<TReqBase>(lRequestBase);
I get the TReqBase serialized: lJSON.AsString = '{"token":-12346789}'
I want to have TReqLogin serialized.
Tried:
lContext.AsJson< TReqLogin >(lRequestBase); won't work: incompatible types) [Besides, I would have to list/handle all possible RequestClass types in my routine]
lContext.AsJson< lRequestBase.ClassType >(lRequestBase) neither: E2531 Method 'AsJson' requires explicit type argument(s)
Is there any way I can have my lRequestBase serialized as a TReqLogin, TReq... without having to code for them all?
The trick is to not create a TSuperRttiContext
and call its AsJSOn method myself, but to immediately use:
lJSON := RequestBase.ToJSON;
The ToJSON method will then create a TSuperRttiContext behind the scenes and handle the necessary conversions.
With a big thank you to Marjan for her help.
这篇关于为通过元类实例化的实例序列化JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!