Delphi 从界面查询自定义属性
Delphi query custom attribute from interface
我已经声明了以下自定义属性
unit SpecialAttribute;
interface
type
TSpecialAttribute = class(TCustomAttribute)
procedure SetValue(aValue: String);
public
FValue: String;
property Value: String read FValue write SetValue;
constructor Create(const AValue: String);
end;
implementation
{ TSpecialAttribute }
constructor TSpecialAttribute.Create(const AValue: String);
begin
FValue := aValue;
end;
procedure TSpecialAttribute.SetValue(aValue: String);
begin
FValue := aValue;
end;
end.
并用于修饰以下界面:
unit ITestInterface;
interface
uses
SpecialAttribute;
type
ITestIntf = interface(IInvokable)
[TSpecialAttribute('IntfAttribute')]
procedure Test;
end;
implementation
end.
我正在尝试使用 RTTI 从接口获取属性:
unit Unit17;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
SpecialAttribute,ITestInterface;
type
TTestClass = class(TInterfacedObject, ITestIntf)
[TSpecialAttribute('TestClass')]
procedure Test;
end;
TForm17 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form17: TForm17;
implementation
uses
Rtti;
{$R *.dfm}
procedure TForm17.FormCreate(Sender: TObject);
var
LContext: TRttiContext;
LType: TRttiType;
LAttr: TCustomAttribute;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for LAttr in LType.GetAttributes() do
if LAttr is TSpecialAttribute then
Memo1.Lines.Add(TSpecialAttribute(LAttr).FValue)
else
Memo1.Lines.Add(LAttr.ClassName);
finally
LContext.Free;
end;
end;
end.
在自定义属性构造函数上设置断点时,代码永远不会停止。如何从接口获取属性?
根据 Remy Lebeau 的评论,我已经设法解决了它。具有以下接口声明:
unit ITestInterface;
interface
uses
SpecialAttribute;
type
[TSpecialAttribute('IntfAttribute - class')]
ITestIntf = interface(IInvokable)
[TSpecialAttribute('IntfAttribute - method')]
procedure Test([TSpecialAttribute('IntfAttribute - params')]i: Integer);
end;
implementation
end.
1) 获取修饰方法的属性:
var
LContext: TRttiContext;
LType: TRttiType;
LAttr: TCustomAttribute;
lMethod: TRttiMethod;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for lMethod in LType.GetMethods do
begin
for LAttr in lMethod.GetAttributes do
if LAttr.ClassType = TSpecialAttribute then
begin
Memo1.Lines.Add(LAttr.ClassName + ' value ' + TSpecialAttribute(LAttr).Value);
end
else
Memo1.Lines.Add(LAttr.ClassName);
end;
finally
LContext.Free;
end;
returns - TSpecialAttribute 值 IntfAttribute - 方法
2) 获取修饰参数的属性:
var
LContext: TRttiContext;
LType: TRttiType;
lMethod: TRttiMethod;
lParam: TRttiParameter;
lAttr: TCustomAttribute;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for lMethod in LType.GetMethods do
begin
for lParam in lMethod.GetParameters do
for lAttr in lParam.GetAttributes do
begin
Memo1.Lines.Add('Attribute ' + lAttr.ClassName + ' found on parameter '+ lParam.Name);
if lAttr.ClassType = TSpecialAttribute then
Memo1.Lines.Add( ' value ' + TSpecialAttribute(lAttr).Value);
end;
end;
finally
LContext.Free;
end;
end;
returns 在参数 i 上找到属性 TSpecialAttribute
值 IntfAttribute - params
3) 获取修饰 class
的属性
var
LContext: TRttiContext;
LType: TRttiType;
LAttr: TCustomAttribute;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for LAttr in LType.GetAttributes() do
if LAttr is TSpecialAttribute then
Memo1.Lines.Add(TSpecialAttribute(LAttr).FValue)
else
Memo1.Lines.Add(LAttr.ClassName);
finally
LContext.Free;
end;
end;
returns IntfAttribute - class
我已经声明了以下自定义属性
unit SpecialAttribute;
interface
type
TSpecialAttribute = class(TCustomAttribute)
procedure SetValue(aValue: String);
public
FValue: String;
property Value: String read FValue write SetValue;
constructor Create(const AValue: String);
end;
implementation
{ TSpecialAttribute }
constructor TSpecialAttribute.Create(const AValue: String);
begin
FValue := aValue;
end;
procedure TSpecialAttribute.SetValue(aValue: String);
begin
FValue := aValue;
end;
end.
并用于修饰以下界面:
unit ITestInterface;
interface
uses
SpecialAttribute;
type
ITestIntf = interface(IInvokable)
[TSpecialAttribute('IntfAttribute')]
procedure Test;
end;
implementation
end.
我正在尝试使用 RTTI 从接口获取属性:
unit Unit17;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
SpecialAttribute,ITestInterface;
type
TTestClass = class(TInterfacedObject, ITestIntf)
[TSpecialAttribute('TestClass')]
procedure Test;
end;
TForm17 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form17: TForm17;
implementation
uses
Rtti;
{$R *.dfm}
procedure TForm17.FormCreate(Sender: TObject);
var
LContext: TRttiContext;
LType: TRttiType;
LAttr: TCustomAttribute;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for LAttr in LType.GetAttributes() do
if LAttr is TSpecialAttribute then
Memo1.Lines.Add(TSpecialAttribute(LAttr).FValue)
else
Memo1.Lines.Add(LAttr.ClassName);
finally
LContext.Free;
end;
end;
end.
在自定义属性构造函数上设置断点时,代码永远不会停止。如何从接口获取属性?
根据 Remy Lebeau 的评论,我已经设法解决了它。具有以下接口声明:
unit ITestInterface;
interface
uses
SpecialAttribute;
type
[TSpecialAttribute('IntfAttribute - class')]
ITestIntf = interface(IInvokable)
[TSpecialAttribute('IntfAttribute - method')]
procedure Test([TSpecialAttribute('IntfAttribute - params')]i: Integer);
end;
implementation
end.
1) 获取修饰方法的属性:
var
LContext: TRttiContext;
LType: TRttiType;
LAttr: TCustomAttribute;
lMethod: TRttiMethod;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for lMethod in LType.GetMethods do
begin
for LAttr in lMethod.GetAttributes do
if LAttr.ClassType = TSpecialAttribute then
begin
Memo1.Lines.Add(LAttr.ClassName + ' value ' + TSpecialAttribute(LAttr).Value);
end
else
Memo1.Lines.Add(LAttr.ClassName);
end;
finally
LContext.Free;
end;
returns - TSpecialAttribute 值 IntfAttribute - 方法
2) 获取修饰参数的属性:
var
LContext: TRttiContext;
LType: TRttiType;
lMethod: TRttiMethod;
lParam: TRttiParameter;
lAttr: TCustomAttribute;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for lMethod in LType.GetMethods do
begin
for lParam in lMethod.GetParameters do
for lAttr in lParam.GetAttributes do
begin
Memo1.Lines.Add('Attribute ' + lAttr.ClassName + ' found on parameter '+ lParam.Name);
if lAttr.ClassType = TSpecialAttribute then
Memo1.Lines.Add( ' value ' + TSpecialAttribute(lAttr).Value);
end;
end;
finally
LContext.Free;
end;
end;
returns 在参数 i 上找到属性 TSpecialAttribute 值 IntfAttribute - params
3) 获取修饰 class
的属性 var
LContext: TRttiContext;
LType: TRttiType;
LAttr: TCustomAttribute;
begin
try
LContext := TRttiContext.Create;
LType := LContext.GetType(TypeInfo(ITestIntf));
for LAttr in LType.GetAttributes() do
if LAttr is TSpecialAttribute then
Memo1.Lines.Add(TSpecialAttribute(LAttr).FValue)
else
Memo1.Lines.Add(LAttr.ClassName);
finally
LContext.Free;
end;
end;
returns IntfAttribute - class