内置编组的类。为什么现场转换器不工作?

时间:2011-09-30 09:26:34

标签: delphi marshalling delphi-xe converter

我有以下问题:

  1. 编组应该放在班助手吗?或者把它“放在”课堂内是否可以?
  2. 为什么现场转换器不工作?
  3. 使用Delphi XE - 考虑一下:

    type
      TMyClass = Class
      public
        FaString : String;
        FaStringList : TStringList; 
        FMar : TJsonMarshal;
        procedure RegisterConverters;
        function Marshal : TJsonObject;  // should handle marshalling
      end;
    

    RegisterConverters看起来像这样。

    procedure TMyClass.RegisterConverters;
    begin
      // try and catch the marshaller itself.
      FMar.RegisterConverter(TJsonMarshal, 'FMar',
        function(Data : TObject; Field:String): TObject
        begin
          Exit(nil); // Since we cannot marshal it - and we dont need it anyways.
        end);
      // catch TStringList
      FMar.RegisterConverter(TStringList, 'FaStringList',
        function(Data: TObject; Field:String): 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);
    end; 
    

    元帅方法:

    function TMyClass.Marshal: TJSONObject;
    begin
      if FMar = nil then
        FMar := TJSONMarshal.Create(TJSONConverter.Create);
      try
        RegisterConverters;
        try
          Result := FMar.Marshal(Self) as TJSONObject;
        except
          Result := nil;
        end;
      finally
        FMar.Free;
      end;
    end;
    

    然后我们可以这样做:

    var
      aObj : TMyClass;
      ResultString : String;
    begin
      aObj := TMyClass.Create;
      aObj.FaString := 'Test string';
      aObj.FaStringList := TStringList.Create;
      aObj.FaStringList.Add('stringliststring #1');
      aObj.FaStringList.Add('stringliststring #2');
      aObj.FaStringList.Add('stringliststring #3');
      aObj.FaStringList.Add('stringliststring #4');
    
      // StringList and JsonMarshal should be handled by converter
      ResultString := (aObj.Marshal).ToString;
    end;
    

    但我根本无法让它发挥作用。现场转换器不会被触发?

    我在这里做错了吗?或者我应该看看我的Delphi XE安装(也许它是pooched)?

1 个答案:

答案 0 :(得分:1)

从“内部”执行编组时,您必须正确设置: - )

procedure TMyClass.RegisterConverters;
begin
  // try and catch the marshaller itself.
  FMar.RegisterConverter(ClassType, 'FMar',
    function(Data : TObject; Field:String): TObject
    begin
      Exit(nil); // Since we cannot marshal it - and we dont need it anyways.
    end);
  // catch TStringList
  FMar.RegisterConverter(ClassType, 'FaStringList',
    function(Data: TObject; Field:String): 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);
end; 

不同之处在于使用ClassType作为RegisterConverter调用中的类型。 否则一个人无法进入指定的领域 - 我应该已经看到了!