具有单个getter和setter的Delphi属性
发布时间:2020-12-15 09:21:05 所属栏目:大数据 来源:网络整理
导读:我正在尝试实现一个配置文件类包装器,并且使用单个函数获取和使用单个函数将值设置为属性会更容易. 下面的代码是我想要实现的最低版本. 欢迎任何帮助. unit Config;interfaceuses Rtti;type Group = class(TCustomAttribute) strict private FName: string;
我正在尝试实现一个配置文件类包装器,并且使用单个函数获取和使用单个函数将值设置为属性会更容易.
下面的代码是我想要实现的最低版本. 欢迎任何帮助. unit Config; interface uses Rtti; type Group = class(TCustomAttribute) strict private FName: string; public constructor Create(const Name: string); property Name: string read FName; end; IConfig = class protected function GetString: string; procedure SetString(const Value: string); end; TConfig = class(IConfig) public [Group('Person')] property Name: string read GetString write SetString; [Group('Person')] property City: string read GetString write SetString; end; implementation { Group } constructor Group.Create(const Name: string); begin FName := Name; end; { IConfig } function IConfig.GetString: string; begin // Here I would need the following from the property that call this function: // * Property name // * Property attribute name // This kind of code will not work,because it loop through all available properties (* var ctx: TRttiContext; objType: TRttiType; Prop: TRttiProperty; begin ctx := TRttiContext.Create; objType := ctx.GetType(Obj.ClassInfo); for Prop in objType.GetProperties do begin if Prop.GetClassType is TClassBase then // do something special with base class properties else // standard functionality on all other properties end; end; *) end; procedure IConfig.SetString(const Value: string); begin // Need the same as above end; end. 解决方法
属性getter和setter不知道哪个属性正在调用它们.共享getter / setter知道的唯一方法是使用索引说明符,例如:
unit Config; interface uses Rtti; type Group = class(TCustomAttribute) strict private FName: string; public constructor Create(const Name: string); property Name: string read FName; end; IConfig = class protected function GetString(Index: Integer): string; procedure SetString(Index: Integer; const Value: string); end; TConfig = class(IConfig) public [Group('Person')] property Name: string index 0 read GetString write SetString; [Group('Person')] property City: string index 1 read GetString write SetString; end; implementation { Group } constructor Group.Create(const Name: string); begin FName := Name; end; { IConfig } function IConfig.GetString(Index: Integer): string; begin case Index of 0: begin // Name ... end; 1: begin // City ... end; ... end; end; procedure IConfig.SetString(Index: Integer; const Value: string); begin // same as above end; end. 如果getter / setter需要知道属性名称,则可以使用RTTI查找具有相应索引值的属性,如果找到,则还可以访问其属性,例如: function GetPropNameAndGroup(Cls: TClass; PropIndex: Integer; var PropName,GroupName: String): Boolean; var Ctx: TRttiContext; Prop: TRttiProperty; Attr: TCustomAttribute; begin PropName := ''; GroupName := ''; Ctx := TRttiContext.Create; for Prop in Ctx.GetType(Cls).GetProperties do begin if (Prop as TRttiInstanceProperty).Index = PropIndex then begin PropName := Prop.Name; for Attr in Prop.GetAttributes do begin if Attr is Group then begin GroupName := Group(Attr).Name; Break; end; end; Break; end; end; Result := (PropName <> '') and (GroupName <> ''); end; function IConfig.GetString(Index: Integer): string; var PropName,GroupName: string; begin if GetPropNameAndGroup(ClassType,Index,PropName,GroupName) then begin //... end; end; procedure IConfig.SetString(Index: Integer; const Value: string); var PropName,GroupName) then begin //... end; end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |