views:

62

answers:

1

I am currently using this code, but does not list anything. What I'm missing?

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.
+2  A: 

Take a look at your compiler warnings. When I build this, I see:

[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'

This is due to a historical quirk. The Delphi for .NET compiler supported attributes, and they're used widely in the VCL for various .NET things. The Delphi for Win32 compiler had to be able to read them and ignore them.

Then Delphi 2010 came out, and Delphi Win32 supported attributes suddenly. But all these .NET attributes didn't exist in Delphi. Instead of rooting them all out, they made the compiler just give a warning and then ignore them. (Also, I believe I heard someone from Emb. say that Delphi for .NET is still used internally for whatever reason.)

As a side-effect, it's perfectly valid to put an attribute that doesn't actually exist on your classes. It will just be ignored by the compiler and no RTTI for it will be generated.

Mason Wheeler
Thanks very much Mason.
Salvador
To add to this, if you want to use custom attributes in your code, and have them be accessible to RTTI, then you need to explicitally define attribute classes in your code. There is a whole chapter in the 2010 documentation on this subject: ms-help://embarcadero.rs2010/rad/Attributes_Index.html
Remy Lebeau - TeamB