gpt4 book ai didi

delphi - 使用 RTTI 获取/设置子属性

转载 作者:行者123 更新时间:2023-12-03 15:42:28 26 4
gpt4 key购买 nike

鉴于下面的代码片段,使用 GetPropValue(MyComponent,'MySubComponent.Prop1') 会引发 EPropertyError 异常。如何使用 GetPropValue/SetPropValue 检索或设置 SubProperties 的值?

Type
TMySubComponent = class(TInterfacedPersitent)
private
FProp1: Integer;
published
property Prop1: integer read FProp1 write FProp1;
end;

TMyComponent = class(TCompoent)
private
FMySubComponent : TMySubcomponent;
published
property MySubComponent: TMySubComponent read FMySubComponent write FMySubComponent ;
end;

最佳答案

正如 Robert 所说,不支持点符号,但您可以轻松创建一个函数来使用 RTTI 设置或获取子属性值。检查此示例

{$APPTYPE CONSOLE}

uses
Rtti,
Classes,
SysUtils;


Type
TMySubComponent = class(TInterfacedPersistent)
private
FProp1: Integer;
published
property Prop1: integer read FProp1 write FProp1;
end;

TMyComponent = class(TComponent)
private
FMySubComponent : TMySubcomponent;
published
property MySubComponent: TMySubComponent read FMySubComponent write FMySubComponent ;
end;



procedure SetObjValueEx(const ObjPath:string;AInstance:TObject;AValue:TValue);
Var
c : TRttiContext;
Prop : string;
SubProp : string;
pm : TRttiProperty;
p : TRttiProperty;
Obj : TObject;
begin
Prop:=Copy(ObjPath,1,Pos('.',ObjPath)-1);
SubProp:=Copy(ObjPath,Pos('.',ObjPath)+1);
c := TRttiContext.Create;
try
for pm in c.GetType(AInstance.ClassInfo).GetProperties do
if CompareText(Prop,pm.Name)=0 then
begin
p := c.GetType(pm.PropertyType.Handle).GetProperty(SubProp);
if Assigned(p) then
begin
Obj:=pm.GetValue(AInstance).AsObject;
if Assigned(Obj) then
p.SetValue(Obj,AValue);
end;
break;
end;
finally
c.Free;
end;
end;


function GetObjValueEx(const ObjPath:string;AInstance:TObject):TValue;
Var
c : TRttiContext;
Prop : string;
SubProp : string;
pm : TRttiProperty;
p : TRttiProperty;
Obj : TObject;
begin
Prop:=Copy(ObjPath,1,Pos('.',ObjPath)-1);
SubProp:=Copy(ObjPath,Pos('.',ObjPath)+1);
c := TRttiContext.Create;
try
for pm in c.GetType(AInstance.ClassInfo).GetProperties do
if CompareText(Prop,pm.Name)=0 then
begin
p := c.GetType(pm.PropertyType.Handle).GetProperty(SubProp);
if Assigned(p) then
begin
Obj:=pm.GetValue(AInstance).AsObject;
if Assigned(Obj) then
Result:=p.GetValue(Obj);
end;
break;
end;
finally
c.Free;
end;
end;

Var
MyComp : TMyComponent;
begin
try
MyComp:=TMyComponent.Create(nil);
try
MyComp.MySubComponent:=TMySubComponent.Create;
//Set the value of the property
SetObjValueEx('MySubComponent.Prop1',MyComp,777);
//Get the value of the property
Writeln(Format('The value of MySubComponent.Prop1 is %d',[GetObjValueEx('MySubComponent.Prop1',MyComp).AsInteger]));
finally
MyComp.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.

关于delphi - 使用 RTTI 获取/设置子属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7649812/

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