2017-01-16 16 views
1

我想連載/ deserialise的TMySerializableClass在下面的單元中聲明:泛型和JSON序列在Delphi XE5反射

unit Unit6; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Generics.Collections, System.SyncObjs, DBXJSon, 
    DBXJSonReflect; 

type 
    TForm6 = class(TForm) 
    Button1: TButton; 
    Memo1: TMemo; 
    procedure Button1Click(Sender: TObject); 
    private 
    public 
    { Public declarations } 
    end; 

    TMySerializableClass<T> = class 
    MyStringField: string; 
    MyIntegerField: Integer; 
    MyBooleanField: Boolean; 
    end; 

var 
    Form6: TForm6; 

implementation 

{$R *.dfm} 

procedure TForm6.Button1Click(Sender: TObject); 
var 
    Mar: TJSONMarshal; //Serializer 
    UnMar: TJSONUnMarshal; //UnSerializer 
    SerializedObject: TJSONObject; 
    aMySerializableClass1: TMySerializableClass<Integer>; 
    aMySerializableClass2: TMySerializableClass<Integer>; 
    aString: string; 
begin 
    try 
    aMySerializableClass1:= TMySerializableClass<Integer>.Create; 
    aMySerializableClass2:= TMySerializableClass<Integer>.Create; 

    Mar:= TJSONMarshal.Create(TJSONConverter.Create); 
    try 
     SerializedObject := Mar.Marshal(aMySerializableClass1) as TJSONObject; 
    finally 
     Mar.Free; 
    end; 
    Memo1.Text:= SerializedObject.ToString; 

    // UnMarshalling Kid 
    UnMar := TJSONUnMarshal.Create; 
    try 
     aMySerializableClass2 := UnMar.UnMarshal(SerializedObject) as TMySerializableClass<Integer>; 
    finally 
     UnMar.Free; 
    end; 
    finally 
    aMySerializableClass1.Free; 
    aMySerializableClass2.Free; 
    end; 
end; 

end. 

當我連載它一切正常,而當deserialise到一個新的實例變量同一種類的,我得到了以下錯誤:

First chance exception at $74E5C41F. Exception class EConversionError with message 'Internal: Cannot instantiate type Unit6.TMySerializableClass<System.Integer>'. Process Project7.exe (2252) 

Edit: this has something to do with the TMySerializableClass<T> , which is a generic. If I declare it as TMySerializableClass the deserialisation works fine.

想法?

+0

你試過TJson.ObjectToJsonString(Foo);從REST.JSON單元? –

回答

0

無法測試上XE5但柏林10.1它爲我工作後,我加入別名泛型類型的實例作爲

TMySerializableClassInteger = TMySerializableClass<Integer>; 

看起來像德爾福不會產生RTTI信息,如果你不這樣做。

UPDATE。似乎德爾福不需要別名,但只需要在單元的界面部分聲明一些專門的類。所以如果你聲明變量或表單域爲TMySerializableClass<Integer>它也可以。

+1

這打破了泛型的使用,不是嗎? – whosrdaddy

+0

這是一個骯髒的伎倆,因爲我必須使用更多的代碼和檢查/實例化不同的類,但我可以忍受這一點爲我現在需要做的。爲了知識的緣故,這可能是Delphi中的一個錯誤,或者我們正在做一些基本錯誤的事情? –

+1

對於未來的讀者,我建議使用https://github.com/onryldz/x-superobject來處理Json相關的問題。單位DBXJSon似乎是越野車,並且REST.JSON也是。 REST.JSON解決了這種情況下的問題(使用泛型類),但它似乎不是一個好的選擇(請參閱此文章:http://stackoverflow.com/questions/31778518/delphi-rest-json-jsontoobject-only -works-with-f-variables) –