我试图用记录和默认数组属性替换显式声明的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.
答案 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;
但我相信你有自己的测试方法。