Delphi 2010 RTTI: используйте TValue для хранения данных - PullRequest
3 голосов
/ 26 января 2010

Я хотел бы иметь возможность использовать TValue для хранения данных в TList <>. Как в:

type
  TXmlBuilder = class
  type
    TXmlAttribute = class
      Name: String;
      Value: TValue; // TValue comes from Rtti
    end;

    TXmlNode = class
      Name: String;
      Parent: TXmlNode;
      Value: TXmlNode;
      Attributes: TList<TXmlAttribute>;
      Nodes: TList<TXmlNode>;
      function AsString(Indent: Integer): String;
    end;
  ...
  public
    ...
    function N(const Name: String): TXmlBuilder;
    function V(const Value: String): TXmlBuilder;
    function A(const Name: String; Value: TValue): TXmlBuilder; overload;
    function A<T>(const Name: String; Value: T): TXmlBuilder; overload;  
    ...
 end;     

implementation

function TXmlBuilder.A(const Name: String; Value: TValue): TXmlBuilder;
var
  A: TXmlAttribute;
begin
  A := TXmlAttribute.Create;
  A.Name := Name;
  A.Value := Value;
  FCurrent.Attributes.Add(A);
  Result := Self;
end;

function TXmlBuilder.A<T>(const Name: String; Value: T): TXmlBuilder;
var
  V: TValue;
begin
  V := TValue.From<T>(Value);
  A(Name, V);
end; 

И чуть позже, в основной программе, я использую свой "свободный" XML-конструктор, например:

b := TXmlBuilder.Create('root');
b.A('attribute', 1).A('other_attribute', 2).A<TDateTime>('third_attribute', Now);

При втором вызове программа вызывает исключение нарушения прав доступа.

Похоже, первое TValue было "освобождено". Действительно ли возможно использовать TValue для хранения данных Variant во время выполнения?

Я знаю, что в Delphi существуют варианты. Мой конструктор XML будет использоваться для (де) сериализации нативных объектов Delphi в XML с использованием RTTI, поэтому я буду использовать TValue везде.

С уважением,

- Пьер Ягер

1 Ответ

3 голосов
/ 26 января 2010

Я нашел ответ. Моя ошибка.

function TXmlBuilder.A<T>(const Name: String; Value: T): TXmlBuilder;
var
  V: TValue;
begin
  V := TValue.From<T>(Value);
  Result := A(Name, V); // I missed the return value
end; 

Извините; -)

...