gpt4 book ai didi

delphi - 作为函数结果的属性具有空属性值?

转载 作者:行者123 更新时间:2023-12-02 07:57:10 24 4
gpt4 key购买 nike

program Test;

{$APPTYPE CONSOLE}

uses
System.SysUtils,
System.Rtti;

function GetPropertyValue(const AObject: TObject; APropertyName: string): TValue;
var
oType: TRttiType;
oProp: TRttiProperty;
begin
oType := TRttiContext.Create.GetType(AObject.ClassType);
if oType <> nil then
begin
oProp := oType.GetProperty(APropertyName);
if oProp <> nil then
Exit(oProp.GetValue(AObject));
end;
Result := TValue.Empty;
end;

function GetAttributePropertyValue(const AClass: TClass; AAttribute: TClass;
AAttributePropertyName: string): TValue;
var
oAttr: TCustomAttribute;
begin
for oAttr in TRttiContext.Create.GetType(AClass).GetAttributes do
if oAttr.InheritsFrom(AAttribute) then
Exit(GetPropertyValue(oAttr, AAttributePropertyName));
Result := nil;
end;

function GetClassAttribute(const AClass: TClass; AAttribute: TClass): TCustomAttribute;
begin
for Result in TRttiContext.Create.GetType(AClass).GetAttributes do
if Result.InheritsFrom(AAttribute) then
Exit;
Result := nil;
end;

type
DescriptionAttribute = class(TCustomAttribute)
private
FDescription: string;
public
constructor Create(const ADescription: string);
property Description: string read FDescription;
end;

constructor DescriptionAttribute.Create(const ADescription: string);
begin
FDescription := ADescription;
end;

type
[Description('MyClass description')]
TMyClass = class(TObject);

var
oAttr: TCustomAttribute;
begin
{ ok, output is 'MyClass description' }
WriteLn(GetAttributePropertyValue(TMyClass, DescriptionAttribute, 'Description').AsString);
{ not ok, output is '' }
oAttr := GetClassAttribute(TMyClass, DescriptionAttribute);
WriteLn(DescriptionAttribute(oAttr).Description);
// WriteLn(oAttr.ClassName); // = 'DescriptionAttribute'
ReadLn;
end.

我需要 rtti 属性。我希望使用函数 GetClassAttribute() 获取属性,但结果不是预期的。

函数GetAttributePropertyValue()的结果是正确的(第一个WriteLn),但函数GetClassAttribute()的结果是具有空描述值的DescriptionAttribute。为什么?

获取属性作为函数结果的正确方法是什么?

TIA 致以最诚挚的问候布兰科

最佳答案

问题是,如果 TRttiContext 超出范围,则在查询信息(包括属性)期间创建的所有 RTTI 相关对象都将被销毁。

当您在属性类上放置析构函数时,您可以验证这一点。

最近版本在 TRttiContext 上引入了 KeepContextDropContext 方法,您可以使用或只是将全局变量放在某处,并使其触发内部通过调用Create或其他方式创建。我通常将 TRttiContext 变量作为类变量放入使用 RTTI 的类中。

KeepContextDropContext 可以在您可能没有一个全局 TRttiContext 实例来确保其生命周期的代码中使用,因为您正在使用其他实例具有自己的 TRttiContext 引用的类、方法和例程 - 例如,请参阅它在 System.Classes 中的使用,其中 BeginGlobalLoading 期间 KeepContext 正在被调用,并且位于 EndGlobalLoading DropContext 中。

关于delphi - 作为函数结果的属性具有空属性值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48445227/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com