Delphi 如何在运行时创建自定义属性并将其附加到字段
How to create and attach custom attribute to field at runtime in Delphi
是否可以以及如何在运行时创建自定义属性并将其附加到字段?
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
我想将值 Empty
的 MyAttribute
注入到在运行时没有它的字段,产生以下输出:
Bar Title
Other Empty
该框架不提供在运行时附加属性的机制。任何这样做的尝试都将涉及破解框架。
属性是编译时的魔法。在 运行 时代你不需要这样的东西。只需创建自己的字典,其中类型和成员(成员可以设置为字符串)是键,属性列表是值。而且,当您需要检查属性时,可以通过两种方式进行 - 常用和在您的字典中。
是否可以以及如何在运行时创建自定义属性并将其附加到字段?
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
我想将值 Empty
的 MyAttribute
注入到在运行时没有它的字段,产生以下输出:
Bar Title
Other Empty
该框架不提供在运行时附加属性的机制。任何这样做的尝试都将涉及破解框架。
属性是编译时的魔法。在 运行 时代你不需要这样的东西。只需创建自己的字典,其中类型和成员(成员可以设置为字符串)是键,属性列表是值。而且,当您需要检查属性时,可以通过两种方式进行 - 常用和在您的字典中。