我可以拥有默认的类属性吗?

时间:2017-10-03 13:38:50

标签: delphi properties record

我试图用记录和默认数组属性替换显式声明的X: array[TypeX] of string
有了一些魔法,我可以让它工作,但前提是我的记录有一个虚拟变量。

我想要编译以下代码(Fail以外的所有内容)。但是当我访问默认属性时,我得到一个荒谬的错误。

unit Test;
interface

type
  TSyntaxNodeType = (ntAddr,ntDeref);
  SyntaxNodeNames = record
  strict private
    class var FData: array[TSyntaxNodeType] of string;
    class function GetItem(const index: TSyntaxNodeType): string; static; inline;
    class constructor Init;
  public
    class property Items[const index: TSyntaxNodeType]: string read GetItem; default;
  end;

implementation
uses SysUtils, TypInfo;

{ TSyntaxNodeNames }

class function SyntaxNodeNames.GetItem(const index: TSyntaxNodeType): string;
begin
  Result:= FData[index];
end;

class constructor SyntaxNodeNames.Init;
var
  value: TSyntaxNodeType;
begin
  for value := Low(TSyntaxNodeType) to High(TSyntaxNodeType) do
    FData[value] := Copy(LowerCase(GetEnumName(TypeInfo(TSyntaxNodeType), Ord(value))), 3);
end;

function Fail: string;
begin
  Result:= SyntaxNodeNames[ntAddr];  //E2029 '(' expected but '[' found
end;

end.

如果我将所有内容更改为非类方法,它会起作用,但我希望记录中没有实例,只有一个类型。我不需要这个实例。 我不想要变量数组,我也不想使用可写常量。

问题
是默认的类属性应该工作,这是一个错误,还是以某种方式被禁止的默认类属性?

更新
这是修复,但我不喜欢我需要一个永远不会实例化的虚拟变量的事实。

type
  TSyntaxNodeNames = record
  strict private
    class var FData: array[TSyntaxNodeType] of string;
    function GetItem(const index: TSyntaxNodeType): string; inline;
    class constructor Init;
  public
    property Items[const index: TSyntaxNodeType]: string read GetItem; default;
  end;

var
  SyntaxNodeNames: TSyntaxNodeNames; //for some reason default does not work on class properties.

implementation
uses SysUtils, TypInfo;

{ TSyntaxNodeNames }

function TSyntaxNodeNames.GetItem(const index: TSyntaxNodeType): string;
begin
  Result:= FData[index];
end;

class constructor TSyntaxNodeNames.Init;
var
  value: TSyntaxNodeType;
begin
  for value := Low(TSyntaxNodeType) to High(TSyntaxNodeType) do
    FData[value] := Copy(LowerCase(GetEnumName(TypeInfo(TSyntaxNodeType), Ord(value))), 3);
end;

function DoesNotFail: string;
begin
  Result:= SyntaxNodeNames[ntAddr];  //Works as intended.
end;

end.

1 个答案:

答案 0 :(得分:1)

记录不是课程,如果你不想要一个实例,那么课程就是你的选择。

这可以按照您的意愿工作,并注意没有实例:

unit Unit13;

interface

type
  TSyntaxNodeType = (ntAddr,ntDeref);

  SyntaxNodeNames = class
  strict private
    class var FData: array[TSyntaxNodeType] of string;
    class function GetItem(const index: TSyntaxNodeType): string; static; inline;
    class constructor Init;
  public
    class property Items[const index: TSyntaxNodeType]: string read GetItem; default;
  end;

implementation
uses SysUtils, TypInfo;

{ TSyntaxNodeNames }

class function SyntaxNodeNames.GetItem(const index: TSyntaxNodeType): string;
begin
  Result:= FData[index];
end;

class constructor SyntaxNodeNames.Init;
var
  value: TSyntaxNodeType;
begin
  for value := Low(TSyntaxNodeType) to High(TSyntaxNodeType) do
    FData[value] := Copy(LowerCase(GetEnumName(TypeInfo(TSyntaxNodeType), Ord(value))), 3);
end;

end.

我从这样的主要表单中调用了这个来测试

procedure TForm10.Button1Click(Sender: TObject);
begin
  Panel1.Caption := SyntaxNodeNames[ntAddr];
end;

但我相信你有自己的测试方法。