Delphi 使用抽象 class 反序列化 JSON
Delphi deserialize JSON with abstract class
我想使用内置函数 TJson.JsonToObject<T>
和 TJson.ObjectToJsonObject
序列化和反序列化一个对象。该对象包含一些嵌套对象,其中之一是抽象类型。有没有机会告诉反序列化器要创建哪个具体对象?我可以为这个嵌套对象使用自定义 JSON拦截器吗?
类定义如下:
type
TAngPos = class (TObject)
strict private
var
FPrimkey: Integer;
FAng_ID: Integer;
FPosNr: Integer;
FArt_ID: Integer;
FPositionstyp: TPositionstyp; // <--- abstract
end;
type
TPositionstyp = class abstract (TObject)
strict protected
var
FArtikel: TArtikel;
end;
type
TPositionstypArtikel = class (TPositionstyp);
type
TPositionstypAngPosKonf = class (TPositionstyp)
strict private
var
FGrundeinheit: TAngPos;
FEinbaukomponenten: TObjectList<TAngPos>;
end;
type
TArtikel = class (TObject)
strict private
var
FPrimkey: Integer;
FStatus: Integer;
FTyp: Integer;
FBeschreibung: string;
FHerstellerNr: string;
end;
对应的JSON是这样的:
对于 TPositionstypArtikel:
{
"primkey": 23930,
"ang_ID": 2400,
"posNr": 40,
"art_ID": 46210,
"positionstyp": { // PositionstypArtikel
"artikel": {
"primkey": 46210,
"status": 1,
"typ": 2,
"beschreibung": "MyDescription",
"herstellerNr": "MyVendorNr"
}
}
}
对于 TPositionstypAngPosKonf
{
"primkey": 2,
"ang_ID": 1,
"posNr": 10,
"art_ID": 44041,
"positionstyp": { // TPositionstypAngPosKonf
"grundeinheit": { // <-- TAngPos
"primkey": 33067,
"ang_ID": 0,
"posNr": 20,
"art_ID": 44092,
"positionstyp": {
"artikel": {
"primkey": 44092,
"status": 2,
"typ": 4,
"beschreibung": "MyDescriptionGrundeinheit",
"herstellerNr": "MyVendorNrGrundeinheit"
}
}
},
"einbaukomponenten": { // <-- TObjectList<TAngPos>
"ownsObjects": true,
"listHelper": [
{
"primkey": 33068,
"ang_ID": 0,
"posNr": 30,
"art_ID": 44399,
"positionstyp": {
"artikel": {
"primkey": 44399,
"status": 2,
"typ": 4,
"beschreibung": "MyDescriptionEinbaukomponente1",
"herstellerNr": "MyVendorNrEinbaukomponente1"
}
}
},
{
"primkey": 33069,
"ang_ID": 0,
"posNr": 40,
"art_ID": 44398,
"positionstyp": {
"artikel": {
"primkey": 44398,
"status": 2,
"typ": 4,
"beschreibung": "MyDescriptionEinbaukomponente2",
"herstellerNr": "MyVendorNrEinbaukomponente2"
}
}
}
]
},
"artikel": {
"primkey": 44041,
"status": 1,
"typ": 3,
"beschreibung": "MyDescriptionKonfKopf",
"herstellerNr": ""
}
}
对象反序列化后,我可以使用 is
运算符检查嵌套对象是否属于特定类型,但不幸的是它既不是 TPositionstypArtikel
也不是 TPositionstypAngPosKonf
。
感谢您的评论。我最终改变了 class 的结构。它不再包含抽象类型,而是一个单独的 TPositionstypAngPosKonf
类型的变量,它可以是 nil
也可以不是。来自 TPositionstyp
的 TArtikel
现在直接居住在 TAngPos
中,而两个 classes TPositionstyp
和 TPositionstypArtikel
不再存在。所以它基本上看起来像这样
type
TAngPos = class (TObject)
strict private
var
FPrimkey: Integer;
FAng_ID: Integer;
FPosNr: Integer;
FArt_ID: Integer;
FArtikel: TArtikel;
FPositionstypAngPosKonf: TPositionstypAngPosKonf; // may be nil
end;
type
TPositionstypAngPosKonf = class (TObject)
strict private
var
FGrundeinheit: TAngPos;
FEinbaukomponenten: TObjectList<TAngPos>;
end;
type
TArtikel = class (TObject)
strict private
var
FPrimkey: Integer;
FStatus: Integer;
FTyp: Integer;
FBeschreibung: string;
FHerstellerNr: string;
end;
我想使用内置函数 TJson.JsonToObject<T>
和 TJson.ObjectToJsonObject
序列化和反序列化一个对象。该对象包含一些嵌套对象,其中之一是抽象类型。有没有机会告诉反序列化器要创建哪个具体对象?我可以为这个嵌套对象使用自定义 JSON拦截器吗?
类定义如下:
type
TAngPos = class (TObject)
strict private
var
FPrimkey: Integer;
FAng_ID: Integer;
FPosNr: Integer;
FArt_ID: Integer;
FPositionstyp: TPositionstyp; // <--- abstract
end;
type
TPositionstyp = class abstract (TObject)
strict protected
var
FArtikel: TArtikel;
end;
type
TPositionstypArtikel = class (TPositionstyp);
type
TPositionstypAngPosKonf = class (TPositionstyp)
strict private
var
FGrundeinheit: TAngPos;
FEinbaukomponenten: TObjectList<TAngPos>;
end;
type
TArtikel = class (TObject)
strict private
var
FPrimkey: Integer;
FStatus: Integer;
FTyp: Integer;
FBeschreibung: string;
FHerstellerNr: string;
end;
对应的JSON是这样的:
对于 TPositionstypArtikel:
{
"primkey": 23930,
"ang_ID": 2400,
"posNr": 40,
"art_ID": 46210,
"positionstyp": { // PositionstypArtikel
"artikel": {
"primkey": 46210,
"status": 1,
"typ": 2,
"beschreibung": "MyDescription",
"herstellerNr": "MyVendorNr"
}
}
}
对于 TPositionstypAngPosKonf
{
"primkey": 2,
"ang_ID": 1,
"posNr": 10,
"art_ID": 44041,
"positionstyp": { // TPositionstypAngPosKonf
"grundeinheit": { // <-- TAngPos
"primkey": 33067,
"ang_ID": 0,
"posNr": 20,
"art_ID": 44092,
"positionstyp": {
"artikel": {
"primkey": 44092,
"status": 2,
"typ": 4,
"beschreibung": "MyDescriptionGrundeinheit",
"herstellerNr": "MyVendorNrGrundeinheit"
}
}
},
"einbaukomponenten": { // <-- TObjectList<TAngPos>
"ownsObjects": true,
"listHelper": [
{
"primkey": 33068,
"ang_ID": 0,
"posNr": 30,
"art_ID": 44399,
"positionstyp": {
"artikel": {
"primkey": 44399,
"status": 2,
"typ": 4,
"beschreibung": "MyDescriptionEinbaukomponente1",
"herstellerNr": "MyVendorNrEinbaukomponente1"
}
}
},
{
"primkey": 33069,
"ang_ID": 0,
"posNr": 40,
"art_ID": 44398,
"positionstyp": {
"artikel": {
"primkey": 44398,
"status": 2,
"typ": 4,
"beschreibung": "MyDescriptionEinbaukomponente2",
"herstellerNr": "MyVendorNrEinbaukomponente2"
}
}
}
]
},
"artikel": {
"primkey": 44041,
"status": 1,
"typ": 3,
"beschreibung": "MyDescriptionKonfKopf",
"herstellerNr": ""
}
}
对象反序列化后,我可以使用 is
运算符检查嵌套对象是否属于特定类型,但不幸的是它既不是 TPositionstypArtikel
也不是 TPositionstypAngPosKonf
。
感谢您的评论。我最终改变了 class 的结构。它不再包含抽象类型,而是一个单独的 TPositionstypAngPosKonf
类型的变量,它可以是 nil
也可以不是。来自 TPositionstyp
的 TArtikel
现在直接居住在 TAngPos
中,而两个 classes TPositionstyp
和 TPositionstypArtikel
不再存在。所以它基本上看起来像这样
type
TAngPos = class (TObject)
strict private
var
FPrimkey: Integer;
FAng_ID: Integer;
FPosNr: Integer;
FArt_ID: Integer;
FArtikel: TArtikel;
FPositionstypAngPosKonf: TPositionstypAngPosKonf; // may be nil
end;
type
TPositionstypAngPosKonf = class (TObject)
strict private
var
FGrundeinheit: TAngPos;
FEinbaukomponenten: TObjectList<TAngPos>;
end;
type
TArtikel = class (TObject)
strict private
var
FPrimkey: Integer;
FStatus: Integer;
FTyp: Integer;
FBeschreibung: string;
FHerstellerNr: string;
end;