AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen
Thema durchsuchen
Ansicht
Themen-Optionen

Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

Ein Thema von Glados · begonnen am 23. Aug 2017 · letzter Beitrag vom 23. Aug 2017
Antwort Antwort
Seite 1 von 2  1 2      
Glados
(Gast)

n/a Beiträge
 
#1

Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:04
Ich möchte gerne einer Funktion einen Enum-Typen als Parameter übergeben.
Das klappt glaube ich
Delphi-Quellcode:
procedure MyFunc<T>(const Param1: string; Enum: T);
begin
end;
Nun möchte ich gerne in einer Schleife auf die einzelnen Inhalte des Enums zugreifen.
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
 ...
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:25
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. TValue ) oder Hard-Casts tricksen
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#3

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:29
Verrätst du mir netterweise wie?
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:33
Verrätst du mir netterweise wie?
Kommt drauf an, was genau du machen willst, also konkreter gesagt, in welcher Form du die einzelnen Werte weiterverwenden willst.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#5

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:36
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));

Geändert von Glados (23. Aug 2017 um 22:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:41
Dann schau dir mal TRttiEnumerationType an. GetMinValue und GetMaxValue sind zwar leider private , aber folgende Methoden könnten dir evtl. schon reichen:
Delphi-Quellcode:
function GetNames: TArray<string>;
class function GetName<T{: enum}>(AValue: T): string; reintroduce; static;
class function GetValue<T{: enum}>(const AName: string): T; static;
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):
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));
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (23. Aug 2017 um 22:45 Uhr)
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#7

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:43
Die Funktionen habe ich alle schon Aber ich weiß halt nicht wie ich durch die Schleife iterieren kann.
GetNames hab ich nicht.
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#8

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:46
Die Funktionen habe ich alle schon Aber ich weiß halt nicht wie ich durch die Schleife iterieren kann.
Schau mal in meinen Edit.

Im Grunde hast du allerdings nur die Möglichkeit über die Ordinalwerte zu iterieren und dann ggfls. wieder in den expliziten Typ zu hardcasten.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#9

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 22:48
Das sieht super kompliziert aus und ich verstehe das nicht.
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.
Das würde mir schon reichen. Denn mit einer anderen Funktion könnte ich dann anhand des Ordinalwerts den String bekommen.
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)

Geändert von Glados (23. Aug 2017 um 23:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#10

AW: Enum-Typ als Parameter übergeben und mit einer Schleife durchgehen

  Alt 23. Aug 2017, 23:20
So in der Art vielleicht:
Delphi-Quellcode:
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;
bzw.
Delphi-Quellcode:
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;
Da gibt es aber noch diverse Fallstricke glaube ich.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (23. Aug 2017 um 23:23 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz