Mar*_*lot 2 delphi oop delphi-11-alexandria
我可以在每个后代类上将一个字段声明为静态字段,而不是为所有后代类共享其值吗?
这是基类:
type
TKpModelViewControllerEntity = class(TInterfacedObject, IKpEntity)
protected
class var ResourceName: string;
procedure Manage;
public
class function Create: IKpEntity;
end;
Run Code Online (Sandbox Code Playgroud)
这是后裔
unit Customers;
type
TCustomers = class(TKpModelViewControllerEntity)
end;
initialization
TCustomers.ResourceName := 'customers/';
Run Code Online (Sandbox Code Playgroud)
还有另一个:
unit Articles;
type
TArticles = class(TKpModelViewControllerEntity)
end;
initialization
TArticles.ResourceName := 'articles/';
Run Code Online (Sandbox Code Playgroud)
当我尝试创建“客户”屏幕 ( TCustomers.Create.Manage) 时,其资源名称具有“articles/”值而不是“customers/”。
有没有办法指示静态字段为每个后代类保存单独的值?
谢谢。
这可以通过属性轻松实现:
type
ResourceNameAttribute = class(TCustomAttribute)
private
FValue: string;
public
constructor Create(const AValue: string);
property Value: string read FValue;
end;
type
TKpModelViewControllerEntity = class(TInterfacedObject, IKpEntity)
protected
class function ResourceName: string;
procedure Manage;
public
class function Create: IKpEntity;
end;
class function TKpModelViewControllerEntity.ResourceName: string;
begin
Result := '';
var ctx := TRttiContext.Create;
var cls := ctx.GetType(Self);
var attr := cls.GetAttribute<ResourceNameAttribute>;
if attr <> nil then
Result := attr.Value;
end;
constructor ResourceNameAttribute.Create(const AValue: string);
begin
inherited Create;
FValue := AValue;
end;
...
type
[ResourceName('customers/')]
TCustomers = class(TKpModelViewControllerEntity)
end;
type
[ResourceName('articles/')]
TArticles = class(TKpModelViewControllerEntity)
end;
Run Code Online (Sandbox Code Playgroud)
我会使用一个class virtual方法而不是一个class var,例如:
type
TKpModelViewControllerEntity = class(TInterfacedObject, IKpEntity)
protected
class function ResourceName: string; virtual;
...
end;
class function TKpModelViewControllerEntity.ResourceName: string;
begin
Result := ''; // or whatever default you want...
end;
Run Code Online (Sandbox Code Playgroud)
type
TCustomers = class(TKpModelViewControllerEntity)
protected
class function ResourceName: string; override;
...
end;
class function TCustomers.ResourceName: string;
begin
Result := 'customers/';
end;
Run Code Online (Sandbox Code Playgroud)
type
TArticles = class(TKpModelViewControllerEntity)
protected
class function ResourceName: string; override;
...
end;
class function TArticles.ResourceName: string;
begin
Result := 'articles/';
end;
Run Code Online (Sandbox Code Playgroud)