如何使用RTTI列出属性的属性?

5
我目前使用这段代码,但没有列出任何内容。我错过了什么?
program ListAttrs;

{$APPTYPE CONSOLE}

uses
  Rtti,
  SysUtils;

type
  TPerson = class
  private
    FName: String;
    FAge: Integer;
  public
    [NonEmptyString('Must provide a Name')]
    property Name : String read FName write FName;
    [MinimumInteger(18, 'Must be at least 18 years old')]
    [MaximumInteger(65, 'Must be no older than 65 years')]
    property Age : Integer read FAge write FAge;
  end;


procedure test;
var
  ctx       : TRttiContext;
  lType     : TRttiType;
  lAttribute: TCustomAttribute;
  lProperty : TRttiProperty;
begin
   ctx       := TRttiContext.Create;
   lType     := ctx.GetType(TPerson);
   for lProperty in lType.GetProperties do
    for lAttribute in lProperty.GetAttributes do
    Writeln(lAttribute.ToString);
end;

begin
  try
     Test;
     Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
1个回答

5

请查看您的编译器警告。当我构建此时,我看到:

[DCC Warning] ListAttrs.dpr(15): W1025 Unsupported language feature: 'custom attribute'
[DCC Warning] ListAttrs.dpr(17): W1025 Unsupported language feature: 'custom attribute'
[DCC Warning] ListAttrs.dpr(18): W1025 Unsupported language feature: 'custom attribute'

这是由于历史上的一个怪异问题。Delphi for .NET编译器支持属性,并且在VCL中广泛用于各种.NET事物。而Delphi for Win32编译器需要能够读取并忽略它们。
然后,Delphi 2010发布了,Delphi Win32突然也支持属性了。但所有这些.NET属性在Delphi中都不存在。他们没有将其全部清除,而是让编译器发出警告,然后忽略它们。(此外,我相信我听到Emb.的某个人说,由于某种原因,Delphi for .NET仍在内部使用。)
作为副作用,将不存在的属性放在类上是完全有效的。它将被编译器忽略,不会生成任何关于它的RTTI。

2
此外,如果您想在代码中使用自定义属性,并希望它们可以访问RTTI,则需要在代码中显式定义属性类。有一个完整的章节在2010年的文档中涉及了这个主题:ms-help://embarcadero.rs2010/rad/Attributes_Index.html - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接