2017-10-03 4 views
0

Ich versuche, eine explizit deklarierte X: array[TypeX] of string durch einen Datensatz und eine Standard-Array-Eigenschaft zu ersetzen.
Mit etwas Magie kann ich es zur Arbeit bringen, aber nur wenn ich eine Dummy-Variable für meinen Rekord habe.Kann ich eine Standardklasseneigenschaft haben?

Ich möchte den folgenden Code kompilieren (alles bis Fail tut). Aber ich bekomme einen unsinnigen Fehler, wenn ich auf die Standardeigenschaft zugreife.

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. 

Wenn ich alles zu Nicht-Klassen-Methoden ändere, funktioniert es, aber ich möchte, dass der Datensatz keine Instanz hat, nur einen Typ. Ich brauche die Instanz nicht. Ich möchte kein Variablenarray, und ich möchte keine schreibbaren Konstanten verwenden.

Frage
Sind Standardklasse Eigenschaften funktionieren sollte und dies ist ein Fehler, oder sind Eigenschaften Standardklasse verboten irgendwie?

UPDATE
Hier ist die Lösung, aber ich weiß nicht, wie die Tatsache, dass ich ein Dummy-Variable benötigen, die nie instanziiert erhalten.

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

Also, was ist die Frage? – Dsm

+0

@Dsm, wie man den obigen Code kompilieren? Kann ich eine Standardklasseneigenschaft haben? – Victoria

+0

@Victoria die Frage hat sich geändert, seit ich gefragt habe ;-) Das Original hatte keine Frage. – Dsm

Antwort

1

Datensätze sind keine Klassen und wenn Sie keine Instanz möchten, sind Klassen der richtige Weg.

Dies funktioniert, wie Sie wollen, und beachten Sie, dass es keine Instanzen sind:

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. 

ich dies aus der Hauptform wie folgt aufgerufen

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

zu testen, aber ich bin sicher, dass Sie Ihre eigenen Testmethoden.

Verwandte Themen