![]() |
Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Hallo zusammen,
wenn ich ein String-Property
Code:
habe und ein zugehöriges Feld
MySet
Code:
vom Typ
FMySet
Code:
dann muss ich manuell einen GETter und einen SETter dafür schreiben. Und sobald neue Ausprägunge dazu kommen (z.B. Giraffe, Känguru), dann muss ich jedesmal auch die Get- und Set-Routinen erweitern.
TMySet = (Hund,Katze,Maus)
Und das ist eine ziemlich lästige aber/und primitive Aufgabe, da es dabei eigentlich immer nur um ein
Code:
geht.
else if Value = "Katze" then
FMySet := Katze else... Müsste es nicht möglich sein, mit Hilfe der RTTI universelle Getter und Setter für Aufzählungstypen zu entwickeln, die die verfügbaren Werte als String ermitteln können und daher in einer Schleife für beliebige Aufzählungen funktionieren würden? Ich habe mich bislang nicht viel mit der RTTI beschäftigt und hätte - bevor ich mich da voll reinhänge - gerne von Erfahreneren eine Einschätzung dazu. Danke im Voraus & sonnige Grüße aus Nürnberg ;-) Freejay |
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
IMO solltest du lieber das eigentliche Problem lösen, nämlich, dass du für eine begrenzte Menge an Möglichkeiten (enum) eine Eigenschaft vom Typ string hast und nicht vom Typ deines enums.
Trotzdem noch etwas zu deiner Frage - klar, kann man irgendwie mit RTTI drauf schießen, ist aber imo unnötig. Delphi bietet die Möglichkeit, konstane statische Arrays über einen Enum zu definieren.
Delphi-Quellcode:
Das ganze kann man natürlich auch generisch und über RTTI lösen, aber dann muss man sich was überlegen, ob aus dem enum Wert die entsprechenden Namen zu ermitteln, sollten die mal nicht 1-zu-1 zusammen passen oder lokalisierbar sein.
uses
StrUtils, SysUtils; type TPet = (Hund,Katze,Maus); const CPetNames: array[TPet] of string = ('Hund','Katze','Maus'); function TryGetEnumValue(const s: string; out value: TPet): Boolean; var i: Integer; begin i := IndexText(s, CPetNames); Result := i > -1; if Result then value := TPet(i); end; Aber nochmal, ich würd lieber mit dem enum Typ arbeiten und erst dort, wo man einen string benötigt (z.B. in der UI) umwandeln. Ansonsten hat man ein ![]() |
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Meinst Du sowas?
Delphi-Quellcode:
Ist ein Fragment aus einer Klasse, mit der ich mir die Dokumantation eines Programmes, einer Klasse ... über RTTI generiere und mit Delphi 7 geschrieben.
uses
Classes, TypInfo; { Die Prozedur liefert Informationen zum übergebenen Aufzählungstypen und gibt } { diese in der Stringliste zurück. } procedure TRTTI.GetEnumTypeInfo(AClass: TObject); begin GetEnumTypeInfo(PTypeInfo(AClass)); end; { Die Prozedur liefert Informationen zum übergebenen Aufzählungstypen und gibt } { diese in der Stringliste zurück. } procedure TRTTI.GetEnumTypeInfo(ATypeInfo: PTypeInfo); var OrdTypeData : PTypeData; TypeNameStr : String; TypeKindStr : String; MinVal : Integer; MaxVal : Integer; i : integer; begin // TTypeData-Pointer holen OrdTypeData := GetTypeData(ATypeInfo); // Typnamen holen TypeNameStr := ATypeInfo.Name; // Typart als String holen TypeKindStr := GetEnumName(TypeInfo(TTypeKind), Integer(ATypeInfo^.Kind)); // Niedrigsten und höchstmöglichen Wert holen MinVal := OrdTypeData^.MinValue; MaxVal := OrdTypeData^.MaxValue; // Informationen in Stringliste übernehmen FHtml.Add('<ul class="dot">'); FHtml.Add('<li><em class="Name">Type Name: ' + TypeNameStr + '</em></li>'); FHtml.Add('<li><em class="Kind">Type Kind: ' + TypeKindStr + '</em></li>'); // Der gibt zuweilen seltsame Abstürze, das Programm ist einfach weg. If ATypeInfo^.Kind in [tkInteger, tkChar, tkEnumeration, tkFloat, tkInt64] Then Begin FHTML.Add('<li style="list-style: none">'); FHtml.Add('<ul class="dot">'); FHtml.Add('<li><em class="MinMax">Min Val: ' + IntToStr(MinVal) + '</em></li>'); FHtml.Add('<li><em class="MinMax">Max Val: ' + IntToStr(MaxVal) + '</em></li>'); // Mögliche Werte und Namen von Aufzählungstypen holen // WordBool geht als Aufzählungstyp von -2147483648 bis 2147483647. // Das ist etwas zuviel, um alle Werte aufzulisten. if (ATypeInfo^.Kind = tkEnumeration) And (UpperCase(TypeNameStr) <> 'WORDBOOL') then Begin FHTML.Add('<li style="list-style: none">'); FHtml.Add('<table class="small">'); Try // Eigentlich sollte man meinen, das MinVal kleiner als MaxVal ist, If MinVal < MaxVal Then Begin for i := MinVal to MaxVal do Begin FHtml.Add('<tr><td class="left" width="10%"><ul class="dot"><li><em class="Value">Value: ' + IntToStr(i) + '</em></li></ul></td>' + '<td class="left" width="30%"><ul class="dot"><li><em class="Value">Name: ' + GetEnumName(ATypeInfo, i) + '</em></li></ul></td></tr>'); End; End Else Begin // ist es aber bei TOleEnum nicht for i := MinVal Downto MaxVal do Begin FHtml.Add('<tr><td class="left" width="10%"><ul class="dot"><li><em class="Value">Value: ' + IntToStr(i) + '</em></li></ul></td>' + '<td class="left" width="30%"><ul class="dot"><li><em class="Value">Name: ' + GetEnumName(ATypeInfo, i) + '</em></li></ul></td></tr>'); End; End; Except FHtml.Add('<tr><td>Values nicht zu ermitteln.</td></tr>'); End; FHtml.Add('</table>'); FHtml.Add('</li>'); End; FHtml.Add('</ul>'); FHtml.Add('</li>'); End Else Begin End; FHtml.Add('</ul>'); end; |
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Zitat:
Dein Vorschlag würde die Anzahl Stellen, an denen etwas gemacht werden muss (wenn neue Werte hinzukommen) immerhin schon mal von 3 auf 2 reduzieren und den pro-Wert-Aufwand zusätzlich verringern. Was mich an dieser (und erst recht an meiner) Lösung trotzdem noch stört, ist, dass ich quasi die gleichen Texte zweimal (bei mir: drei mal) im Code aufführen und ergänzen muss (Hund und 'Hund')... |
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Zitat:
|
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Ungetestet EntHTMLisiert und GeShowMessaged ;-)
Delphi-Quellcode:
uses
Classes, TypInfo; { Die Prozedur liefert Informationen zum übergebenen Aufzählungstypen. } procedure TRTTI.GetEnumTypeInfo(AClass: TObject); begin GetEnumTypeInfo(PTypeInfo(AClass)); end; { Die Prozedur liefert Informationen zum übergebenen Aufzählungstypen. } procedure TRTTI.GetEnumTypeInfo(ATypeInfo: PTypeInfo); var OrdTypeData : PTypeData; TypeNameStr : String; TypeKindStr : String; MinVal : Integer; MaxVal : Integer; i : integer; begin // TTypeData-Pointer holen OrdTypeData := GetTypeData(ATypeInfo); // Typnamen holen TypeNameStr := ATypeInfo.Name; // Typart als String holen TypeKindStr := GetEnumName(TypeInfo(TTypeKind), Integer(ATypeInfo^.Kind)); // Niedrigsten und höchstmöglichen Wert holen MinVal := OrdTypeData^.MinValue; // Kleinster Wert MaxVal := OrdTypeData^.MaxValue; // Höchster Wert // Type Name = TypeNameStr // Type Kind = TypeKindStr If ATypeInfo^.Kind in [tkInteger, tkChar, tkEnumeration, tkFloat, tkInt64] Then Begin if (ATypeInfo^.Kind = tkEnumeration) And (UpperCase(TypeNameStr) <> 'WORDBOOL') then Begin Try // Eigentlich sollte man meinen, das MinVal kleiner als MaxVal ist, If MinVal < MaxVal Then Begin for i := MinVal to MaxVal do Begin // Verbale Beschreibung = GetEnumName(ATypeInfo, i) // Also z. B. Hund ShowMessage(GetEnumName(ATypeInfo, i)); End; End Else Begin // ist es aber bei TOleEnum nicht for i := MinVal Downto MaxVal do Begin // Verbale Beschreibung = GetEnumName(ATypeInfo, i) // Also z. B. Hund ShowMessage(GetEnumName(ATypeInfo, i)); End; End; Except // Fehlerbehandlung End; End; End; end; |
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Zitat:
Werde ich "die Tage" mal ausprobieren. Vielen Dank! |
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Zitat:
|
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Wieso nicht, das Original ist ja nun mal auch unübersichtlich ;-)
Wesentlich wäre: Liefert die die Routine ansatzweise im ShowMessage solche Werte, wie Du erwartest? Ansonsten ist's ja vergeblich :-( Oh, da fand ich noch dashier: ![]() |
AW: Automatischer Setter/Getter für Aufzählungs-Variablen via RTTI?
Das kann ich frühestens morgen testen.
Gebe dann nochmal Rückmeldung. Danke nochmal! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz