如何在Delphi中在运行时创建自定义属性并将其附加到字段

时间:2015-03-28 12:59:58

标签: delphi attributes rtti

是否可以以及如何在运行时创建自定义属性并将其附加到字段?

uses
  System.SysUtils,
  System.Classes,
  System.Rtti;

type
  MyAttribute = class(TCustomAttribute)
  private
    fCaption: string;
  public
    constructor Create(const aCaption: string);
    property Caption: string read fCaption write fCaption;
  end;

  TFoo = class(TPersistent)
  public
    [MyAttribute('Title')]
    Bar: string;
    Other: string;
  end;

constructor MyAttribute.Create(const aCaption: string);
begin
  fCaption := aCaption;
end;

procedure CreateAttributes(Typ: TRttiType);
var
  Field: TRttiField;
  MyAttr: MyAttribute;
begin
  for Field in Typ.GetFields do
    begin
      if Length(Field.GetAttributes) = 0 then
        begin
          MyAttr := MyAttribute.Create('Empty');
          // how to attach created attribute to Field ???
        end;
    end;
end;

var
  Context: TRttiContext;
  Typ: TRttiType;
  Field: TRttiField;
  Attr: TCustomAttribute;

begin
  Context := TRttiContext.Create;
  Typ := Context.GetType(TFoo);

  CreateAttributes(Typ);

  for Field in Typ.GetFields do
    for Attr in Field.GetAttributes do
      if Attr is MyAttribute then 
        writeln(Field.Name + ' ' + MyAttribute(Attr).Caption);
  readln;
  Context.Free;
end.

在代码上运行会产生输出:

Bar Title

我想将MyAttribute注入价值Empty给不会在运行时生成以下输出的字段:

Bar Title
Other Empty

2 个答案:

答案 0 :(得分:2)

框架没有提供在运行时附加属性的机制。任何这样做的尝试都涉及破解框架。

答案 1 :(得分:0)

属性是编译时魔术。在运行时你不需要这样的东西。只需创建自己的字典,其中类型和成员(成员可以设置为字符串)是键,属性列表是值。并且,当您需要检查属性时,请通过两种方式执行 - 常见和字典。