Класс со встроенной сортировкой.Почему полевые преобразователи не работают? - PullRequest
2 голосов
/ 30 сентября 2011

У меня есть следующие вопросы:

  1. Должен ли маршаллинг быть помещен в помощник класса? Или вполне нормально поместить его «внутри» класса?
  2. Почему преобразователи поля не работают?

Использование 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 (возможно, она установлена)?

1 Ответ

1 голос
/ 02 октября 2011

При выполнении маршала "изнутри" вы должны правильно его настроить: -)

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. Иначе нельзя попасть в указанное поле - я бы это увидел!

...