Delphi 2010 RTTI:使用TValue存储数据

发布于 2024-08-19 01:18:12 字数 1529 浏览 8 评论 0原文

我希望能够使用 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 在运行时存储“变体”数据?

我知道 Delphi 中存在变体。我的 XML 生成器将用于使用 RTTI 将本机 delphi 对象序列化(反)序列化为 XML,因此我将在任何地方使用 TValue。

问候,

- 皮埃尔·雅格

I would like to be able to use TValue to store Data in a TList<>. Like in :

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; 

And a bit later, in the main program, I use my "fluent" xml builder like this :

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

On the second call, the program raises an access violation exception.

It looks like the first TValue has been "freed". Is it really possible to use TValue to store "Variant" data a runtime ?

I know that Variants exists in Delphi. My XML builder will be used to (de)serialize native delphi objects to XML using RTTI so I will be using TValue everywhere.

regards,

--
Pierre Yager

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪落纷纷 2024-08-26 01:18:12

我找到了答案。我的错误。

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; 

对不起 ;-)

I found the answer. My mistake.

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; 

Sorry ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文