瀏覽代碼

Update the Json/Yaml TList<T> deserialization to work with other TList types, not only <TObject>

Vladimir Georgiev 3 年之前
父節點
當前提交
bdb0307d32
共有 2 個文件被更改,包括 32 次插入19 次删除
  1. 15 11
      Quick.Json.Serializer.pas
  2. 17 8
      Quick.YAML.Serializer.pas

+ 15 - 11
Quick.Json.Serializer.pas

@@ -620,10 +620,11 @@ var
   i : Integer;
   n : Integer;
   rProp : TRttiProperty;
-  {$IFNDEF DELPHIRX10_UP}
+  {$IFDEF DELPHIRX10_UP}
+  rMethod: TRttiMethod;
+  {$ELSE}
   rfield : TRttiField;
   {$ENDIF}
-  genericType : TGenericListType;
 begin
   Result := aObject;
 
@@ -654,17 +655,20 @@ begin
   if not rValue.IsEmpty then
   begin
     {$IFDEF DELPHIRX10_UP}
-    if (TObjectList<TObject>(aObject) <> nil) and (rvalue.IsArray) then
+    if (aObject <> nil) and (rvalue.IsArray) then
     begin
-      genericType := GetGenericListType(aObject);
-      if genericType = TGenericListType.gtObjectList then TObjectList<TObject>(aObject).Clear
-        else TList<TObject>(aObject).Clear;
+      rMethod := ctx.GetType(aObject.ClassType).GetMethod('Clear');
+      if rMethod = nil then
+        raise EJsonDeserializeError.Create('Unable to find RTTI method');
+      rMethod.Invoke(aObject, []);
+
+      rMethod := ctx.GetType(aObject.ClassType).GetMethod('Add');
+      if rMethod = nil then
+        raise EJsonDeserializeError.Create('Unable to find RTTI method');
+
       n := rvalue.GetArrayLength - 1;
       for i := 0 to n do
-      begin
-        if genericType = TGenericListType.gtObjectList then TObjectList<TObject>(aObject).Add(rvalue.GetArrayElement(i).AsObject)
-          else TList<TObject>(aObject).Add(rvalue.GetArrayElement(i).AsObject);
-      end;
+        rMethod.Invoke(aObject, [rvalue.GetArrayElement(i)]);
     end;
     {$ELSE}
     n := 0;
@@ -1256,7 +1260,7 @@ begin
       //get list array
       propvalue := GetPropertyValueFromObject(aObject,'List');
       {$IFDEF DELPHIRX10_UP}
-      Result := TJSONObject(SerializeDynArray(propvalue,TList<TObject>(aObject).Count));
+      Result := TJSONObject(SerializeDynArray(propvalue));
       {$ELSE}
       Result := TJSONObject(SerializeValue(propvalue));
       {$ENDIF}

+ 17 - 8
Quick.YAML.Serializer.pas

@@ -486,7 +486,10 @@ var
   rvalue : TValue;
   i : Integer;
   rProp : TRttiProperty;
-  {$IFNDEF DELPHIRX103_UP}
+  {$IFDEF DELPHIRX103_UP}
+  rMethod: TRttiMethod;
+  n: Integer;
+  {$ELSE}
   rfield : TRttiField;
   {$ENDIF}
 begin
@@ -509,14 +512,20 @@ begin
   if not rValue.IsEmpty then
   begin
     {$IFDEF DELPHIRX103_UP}
-    if (TObjectList<TObject>(aObject) <> nil) and (rvalue.IsArray) then
+    if (aObject <> nil) and (rvalue.IsArray) then
     begin
-      TObjectList<TObject>(aObject).Clear;
-      TObjectList<TObject>(aObject).Capacity := rvalue.GetArrayLength;
-      for i := 0 to rvalue.GetArrayLength - 1 do
-      begin
-        TObjectList<TObject>(aObject).Add(rvalue.GetArrayElement(i).AsObject);
-      end;
+      rMethod := ctx.GetType(aObject.ClassType).GetMethod('Clear');
+      if rMethod = nil then
+        raise EYamlDeserializeError.Create('Unable to find RTTI method');
+      rMethod.Invoke(aObject, []);
+
+      rMethod := ctx.GetType(aObject.ClassType).GetMethod('Add');
+      if rMethod = nil then
+        raise EYamlDeserializeError.Create('Unable to find RTTI method');
+
+      n := rvalue.GetArrayLength - 1;
+      for i := 0 to n do
+        rMethod.Invoke(aObject, [rvalue.GetArrayElement(i)]);
     end;
     {$ELSE}
     for rfield in rType.GetFields do