Лучше упомяните это:
Я использую Delphi XE2 - но XE или 2010 тоже должны с этим справиться: -)
Этот вопрос сейчас в Quality Central QC # 99313 , пожалуйста, проголосуйте: -)
По состоянию на 10-20-2011 Embarcadero пометил отчет о КК как РАЗРЕШЕННЫЙ.
Решение было предоставлено SilverKnight. Но отсутствие информации от Embarcadero беспокоит меня. Поскольку решение предлагает использовать другой исходный код, который не описан в справочной системе XE (2), других форумах и CC. Но посмотрите на КК самостоятельно.
С учетом этих объявлений типов:
type
TTestObject : Class
aList : TStringList;
function Marshal : TJSonObject;
end;
TTestObjectList<T:TestObject> : Class(TObjectList<T>)
function Marshal : TJSonObject; // How to write this ?
end;
Я хотел бы реализовать метод Marshal для TTestObjectList.
Насколько мне известно - я должен зарегистрировать конвертер для TTestObject и для красоты
об этом - вызвать маршала для каждого элемента.
Маршал для TTestObject регистрирует этот конвертер:
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);
Общий метод маршала TTestObjectList:
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;
Вот упрощенный пример использования списка.
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;
Конечно, у меня есть аналогичные функции для восстановления (unmarshal).
Но приведенный выше код должен работать - по крайней мере, насколько мне известно.
Так что, если кто-нибудь может указать мне:
Почему список не удается маршалировать?
Я знаю, что в моем списке есть свойство TJsonMarshal, но у него также есть конвертер / ревертер.
Изменение на TTypeStringConverter (вместо TTypeObjectConverter) вернет допустимую строку. Но мне нравится идея работать над TJsonObject все время. В противном случае у меня возникла бы такая же проблема (или что-то подобное) при выполнении демаршаллинга из строки в TTestObject.
Любые советы / идеи приветствуются.