本文介绍了泛型和元帅/ UnMarshal。我在这里缺少什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更好地提到这一点:$ b​​ $ b我正在使用Delphi XE2 - 但是XE或2010也应该这样做: - )



现在在质量中心请投票:-)



截至10-20-2011,Embarcadero已将QC报告标记为RESOLVED。
解决方案由SilverKnight提供。但是,Embarcadero的信息不足让我担心。由于该解决方案建议使用其他源代码,而不是XE(2)帮助系统,其他论坛和CC中所述的源代码。



给定这些类型声明:

  type 
TTestObject:Class
aList:TStringList;
函数元组:TJSonObject;
结束

TTestObjectList< T:TestObject> :Class(TObjectList< T>)
函数Marshal:TJSonObject; //如何写这个?
结束

我想实现TTestObjectList的Marshal方法。
据我所知,我应该为TTestObject注册一个转换器,并为每个元素的美元
注册。



元帅对于TTestObject注册此转换器:

  RegisterConverter(TStringList,
function(Data:TObject)):TListOfStrings
var
i,Count:Integer;
begin
计数:= TStringList(Data).Count;
SetLength(Result,Count);
for i:= 0 to Count - 1 do
结果[i]:= TStringList(Data)[i];
end);

Generic TTestObjectList Marshal方法:

  function TTestObjectList< T> .Marshal:TJSONObject; 
var
Mar:TJsonMarshal; //实际上是列表中的一个属性。
begin
Mar:= TJsonMarshal.Create(TJSONConverter.Create);
try
RegisterConverter(TTestObject,
function(Data:TObject)):TObject
begin
结果:= TTestObject(Data).Marshal;
end) ;
结果:= Mar.Marshal(Self)as TJSONObject;
finally
Mar.Free;
结束
结束

以下是使用列表的简化示例。

  var 
aTestobj:TTestObject;
aList:TTestObjectList< TTestObject> ;;
aJsonObject:TJsonObject;
begin
aTestObj:= TTestObject.Create; //构造函数使用虚拟数据创建并填充TStringlist。
aJsonObject:= aTestObj.Marshal; //这样工作。

aList:= TTestObjectList< TTestObject> .Create;
aJsonObject:= aList.Marshal; // fk与tkpointer是未知的....
end;

当然,我有类似的恢复(unmarshal)功能。
但是上面的代码应该可以工作 - 至少在我的知识上。



所以如果有人可以指出我:



为什么列表无法组织?



我知道我的列表中有TJsonMarshal属性,但它也有一个转换器/还原器。 / p>

更改为TTypeStringConverter(而不是TTypeObjectConverter)将返回一个有效的字符串。但我喜欢一直在TJsonObject上工作的想法。否则我会有一个同样的问题(或类似的东西)做一个字符串到TTestObject的解组。



任何建议/想法是最受欢迎的。 b $ b

解决方案

我不知道为什么你得到这个错误。以下似乎适用于我,在Delphi XE中:

 程序Project1; 

{$ APPTYPE CONSOLE}

使用
SysUtils,Classes,Contnrs,
Genericics.Defaults,Genericics.Collections,
DbxJson, DbxJsonReflect;

type
TTestObject = class(TObject)
aList:TStringList;
函数元组:TJSonObject;
public
构造函数创建;
析构函数覆盖
结束

TTestObjectList< T:TTestObject,构造函数> = class(TObjectList< T>)
函数Marshal:TJSonObject;
构造函数创建;
结束

{TTestObject}

构造函数TTestObject.Create;
开始
继承创建;
aList:= TStringList.Create;
aList.Add('one');
aList.Add('two');
aList.Add('three');
结束

析构函数TTestObject.Destroy;
begin
aList.Free;
继承;
结束

函数TTestObject.Marshal:TJSonObject;
var
元帅:TJSONMarshal;
begin
Marshal:= TJSONMarshal.Create(TJSONConverter.Create);
try
Marshal.RegisterConverter(TStringList,
function(Data:TObject):TListOfStrings
var
I,Count:Integer;
begin
计数:= TStringList(Data).Count;
SetLength(Result,Count);
for I:= 0 to Count - 1 do
结果[I]:= TStringList(Data) [I];
end
);
结果:= Marshal.Marshal(Self)as TJSONObject;
finally
Marshal.Free;
结束
结束

{TTestObjectList< T> }

构造函数TTestObjectList< T> .Create;
开始
继承创建;
Add(T.Create);
Add(T.Create);
结束

函数TTestObjectList&T; .Marshal:TJSonObject;
var
元帅:TJsonMarshal;
begin
Marshal:= TJSONMarshal.Create(TJSONConverter.Create);
try
Marshal.RegisterConverter(TTestObject,
function(Data:TObject)):TObject
begin
结果:= T(Data).Marshal;
结束
);
结果:= Marshal.Marshal(Self)as TJSONObject;
finally
Marshal.Free;
结束
结束

程序主;
var
aTestobj:TTestObject;
aList:TTestObjectList< TTestObject> ;;
aJsonObject:TJsonObject;
begin
aTestObj:= TTestObject.Create;
aJsonObject:= aTestObj.Marshal;
Writeln(aJsonObject.ToString);

Writeln;
aList:= TTestObjectList< TTestObject> .Create;
aJsonObject:= aList.Marshal;
Writeln(aJsonObject.ToString);

Readln;
结束

开始
尝试
主;
除了
在E:异常do
开始
ExitCode:= 1;
Writeln(Format('[%s]%s',[E.ClassName,E.Message]));
结束
结束
结束。


Better mention this :I'm using Delphi XE2 - but XE or 2010 should do the trick too :-)

This Question is now in Quality Central QC#99313 please vote it up :-)

As of 10-20-2011 Embarcadero has marked the QC report as RESOLVED.Solution was provided by SilverKnight. But the lack of information from Embarcadero worries me. Since the solution suggests using other source code than the one explained in XE(2) Help system, other forums and CC. But have a look at the QC yourself.

Given these type declarations:

type
TTestObject : Class
    aList : TStringList;
    function Marshal : TJSonObject;
  end;

  TTestObjectList<T:TestObject> : Class(TObjectList<T>)
    function Marshal : TJSonObject; // How to write this ? 
  end;

I would like to implement a Marshal method for TTestObjectList.To my best knowledge - I should register a converter for TTestObject and for the beautyof it - call Marshal for each element.

The Marshal for TTestObject registers this converter:

RegisterConverter(TStringList,
  function(Data: TObject): TListOfStrings
  var
    i, Count: Integer;
  begin
    Count := TStringList(Data).Count;
    SetLength(Result, Count);
    for i := 0 to Count - 1 do
      Result[i] := TStringList(Data)[i];
  end);

The Generic TTestObjectList Marshal method:

function TTestObjectList<T>.Marshal: TJSONObject;
var
Mar : TJsonMarshal;  // is actually a property on the list.
begin
  Mar := TJsonMarshal.Create(TJSONConverter.Create);
  try
    RegisterConverter(TTestObject,
      function(Data: TObject): TObject
      begin
        Result := TTestObject(Data).Marshal;
      end);
    Result := Mar.Marshal(Self) as TJSONObject;
  finally
    Mar.Free;
  end;
end;

Here is a simplified example of using the list.

var
  aTestobj : TTestObject; 
  aList : TTestObjectList<TTestObject>;
  aJsonObject : TJsonObject;
begin
  aTestObj := TTestObject.Create; // constructor creates and fills TStringlist with dummy data.
  aJsonObject := aTestObj.Marshal; // This works as intended.

  aList := TTestObjectList<TTestObject>.Create;
  aJsonObject := aList.Marshal; // Fails with tkpointer is unknown .... 
end;

Of course I have similar functionality for restoring (unmarshal).But the above code should work - at least to my best knowledge.

So if anyone can point out to me :

Why the List fails to marshal?

I know I have the TJsonMarshal property on my list - but it also has a converter/reverter.

Changing to a TTypeStringConverter (instead of TTypeObjectConverter) will return a valid string. But I like the idea of working on a TJsonObject all along. Otherwise I would have the same problem (or something similar) when doing the unmarshalling from a string to TTestObject.

Any advice / ideas are most welcome.

解决方案

I'm not sure why you get that error. The following seems to work for me, in Delphi XE:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, Contnrs,
  Generics.Defaults, Generics.Collections,
  DbxJson, DbxJsonReflect;

type
  TTestObject = class(TObject)
    aList : TStringList;
    function Marshal : TJSonObject;
  public
    constructor Create;
    destructor Destroy; override;
  end;

  TTestObjectList<T:TTestObject,constructor> = class(TObjectList<T>)
    function Marshal: TJSonObject;
    constructor Create;
  end;

{ TTestObject }

constructor TTestObject.Create;
begin
  inherited Create;
  aList := TStringList.Create;
  aList.Add('one');
  aList.Add('two');
  aList.Add('three');
end;

destructor TTestObject.Destroy;
begin
  aList.Free;
  inherited;
end;

function TTestObject.Marshal: TJSonObject;
var
  Marshal: TJSONMarshal;
begin
  Marshal := TJSONMarshal.Create(TJSONConverter.Create);
  try
    Marshal.RegisterConverter(TStringList,
      function (Data: TObject): TListOfStrings
      var
        I, Count: Integer;
      begin
        Count := TStringList(Data).Count;
        SetLength(Result, Count);
        for I := 0 to Count - 1 do
          Result[I] := TStringList(Data)[I];
      end
      );
    Result := Marshal.Marshal(Self) as TJSONObject;
  finally
    Marshal.Free;
  end;
end;

{ TTestObjectList<T> }

constructor TTestObjectList<T>.Create;
begin
  inherited Create;
  Add(T.Create);
  Add(T.Create);
end;

function TTestObjectList<T>.Marshal: TJSonObject;
var
  Marshal: TJsonMarshal;
begin
  Marshal := TJSONMarshal.Create(TJSONConverter.Create);
  try
    Marshal.RegisterConverter(TTestObject,
      function (Data: TObject): TObject
      begin
        Result := T(Data).Marshal;
      end
      );
    Result := Marshal.Marshal(Self) as TJSONObject;
  finally
    Marshal.Free;
  end;
end;

procedure Main;
var
  aTestobj : TTestObject;
  aList : TTestObjectList<TTestObject>;
  aJsonObject : TJsonObject;
begin
  aTestObj := TTestObject.Create;
  aJsonObject := aTestObj.Marshal;
  Writeln(aJsonObject.ToString);

  Writeln;
  aList := TTestObjectList<TTestObject>.Create;
  aJsonObject := aList.Marshal;
  Writeln(aJsonObject.ToString);

  Readln;
end;

begin
  try
    Main;
  except
    on E: Exception do
    begin
      ExitCode := 1;
      Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
    end;
  end;
end.

这篇关于泛型和元帅/ UnMarshal。我在这里缺少什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 10:55