![]() |
Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Ich möchte gerne einer Funktion einen Enum-Typen als Parameter übergeben.
Das klappt glaube ich
Delphi-Quellcode:
Nun möchte ich gerne in einer Schleife auf die einzelnen Inhalte des Enums zugreifen.
procedure MyFunc<T>(const Param1: string; Enum: T);
begin end; Mit einem festen Enum-Typen in der procedure ist das ja einfach. Aber wie sieht das aus, wenn der Enum-Typ jeder Enum sein kann? Was ich bisher habe und was nicht funktioniert
Delphi-Quellcode:
var i: Integer;
begin for i := Low(Enum) to High(Enum) do ... |
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Tja, da bist du an eine Grenze der Delphi Generics gestoßen. Da Delphi netterweise keine Constraints auf Enums erlaubt (warum auch immer man das nach Jahren nicht schafft; sollte eigentlich trivial zu implementieren sein), kannst du hier leider höchstens mit Umweg über die RTTI (z.b.
Delphi-Quellcode:
) oder Hard-Casts tricksen :?
TValue
|
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Verrätst du mir netterweise wie? :pale:
|
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Zitat:
|
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Mit dem genauen Typen vorher bin ich mit Low(DerEnumTyp) und High(DerEnumTyp) durchiteriert.
Und mit der Funktion hier unten habe ich mir den aktuellen Wert als String geholt. Mehr passiert da nicht
Delphi-Quellcode:
function GetName<T>(Value: T): string;
begin Result := System.Rtti.TRttiEnumerationType.GetName(Value); end; var: i: DerEnumTyp; begin for i := Low(DerEnumTyp) to High(DerEnumTyp) do s := GetName(DerEnumTyp(i)); |
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Dann schau dir mal
Delphi-Quellcode:
an.
TRttiEnumerationType
Delphi-Quellcode:
und
GetMinValue
Delphi-Quellcode:
sind zwar leider
GetMaxValue
Delphi-Quellcode:
, aber folgende Methoden könnten dir evtl. schon reichen:
private
Delphi-Quellcode:
Ansonsten hätte ich hier noch eine Möglichkeit explizit an Min und Max zu gelangen (Auszug aus einem Code, der den generischen Enum Typ in einen Ordinalwert konvertiert und dabei zur Sicherheit einige Assertions aufgrund der RTTI Infos ausführt):
function GetNames: TArray<string>;
class function GetName<T{: enum}>(AValue: T): string; reintroduce; static; class function GetValue<T{: enum}>(const AName: string): T; static;
Delphi-Quellcode:
var
TypeInfo: PTypeInfo; TypeData: PTypeData; V: Integer; begin Assert(SizeOf(V) >= SizeOf(T)); TypeInfo := System.TypeInfo(T); Assert(Assigned(TypeInfo) and (TypeInfo^.Kind = tkEnumeration)); TypeData := System.TypInfo.GetTypeData(TypeInfo); V := 0; Move(Value, V, SizeOf(T)); Assert((V >= TypeData^.MinValue) and (V <= TypeData^.MaxValue)); |
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Die Funktionen habe ich alle schon :P Aber ich weiß halt nicht wie ich durch die Schleife iterieren kann.
GetNames hab ich nicht. |
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Zitat:
Im Grunde hast du allerdings nur die Möglichkeit über die Ordinalwerte zu iterieren und dann ggfls. wieder in den expliziten Typ zu hardcasten. |
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Das sieht super kompliziert aus und ich verstehe das nicht.
Zitat:
Wie sähe das denn aus mit dem Ordinalwert? Meins oben funktioniert ja leider nicht. Also im Grunde möchte ich meiner Funktion mehrere Enum-Typen übergeben können ("MeinEnum",... NICHT MeinEnum.XYZ) |
AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
So in der Art vielleicht:
Delphi-Quellcode:
bzw.
procedure TForm1.Test<T>;
var TypeInfo: PTypeInfo; TypeData: PTypeData; I: Integer; V: T; begin TypeInfo := System.TypeInfo(T); Assert(Assigned(TypeInfo) and (TypeInfo^.Kind = tkEnumeration)); TypeData := System.TypInfo.GetTypeData(TypeInfo); for I := TypeData^.MinValue to TypeData^.MaxValue do begin Move(I, V, SizeOf(T)); ShowMessage(TRttiEnumerationType.GetName<T>(V)); end; end;
Delphi-Quellcode:
Da gibt es aber noch diverse Fallstricke glaube ich.
procedure TForm1.Test<T>;
var TypeInfo: PTypeInfo; TypeData: PTypeData; I: Integer; V: T absolute I; begin TypeInfo := System.TypeInfo(T); Assert(Assigned(TypeInfo) and (TypeInfo^.Kind = tkEnumeration)); TypeData := System.TypInfo.GetTypeData(TypeInfo); for I := TypeData^.MinValue to TypeData^.MaxValue do begin ShowMessage(TRttiEnumerationType.GetName<T>(V)); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:22 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