Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Anzahl der Elemente eines Aufzählungstyps ermitteln (https://www.delphipraxis.net/104698-anzahl-der-elemente-eines-aufzaehlungstyps-ermitteln.html)

Ares 9. Dez 2007 13:11


Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Hallo!

Kann man irgendwie die Anzahl der Elemente eines Aufzählungstyps ermitteln?

Delphi-Quellcode:
type
  TMyEnum = (meEins, meZwei, meDrei);
  ...
 
  int := length(TMyEnum);
In diesem Beispiel sollte also int der Wert 3 zugewiesen werden, weil der Aufzählungstyp TMyEnum drei Elemente hat... Nur geht dies eben nicht mit length. Gibt es eine entsprechende Methode, die dies leistet?

Besten Dank
Ares

Apollonius 9. Dez 2007 13:14

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Wenn du einfache Aufzählungen verwendest, kannst du Ord(High(Typ))+1 verwenden. High(TMyEnum) wäre bei dir meDrei und Ord(meDrei) entsprechend 2. Das geht jedoch nicht, wenn du die ordinalen Werte selbst vergibst, z.b.
Delphi-Quellcode:
TMyEnum = (meEins = 100, meZwei = 53, meDrei = 42);

Bernhard Geyer 9. Dez 2007 13:20

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Delphi-Quellcode:
var
  i: TMyEnum;
  Zahler: Integer;
begin
  Zahler := 0;
  for i := Low(TMyEnum) to High(TMyEnum) do
    Inc(Zaehler);
end;

himitsu 9. Dez 2007 13:34

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
@Bernhard Geyer :zwinker:
Delphi-Quellcode:
Anzahl := High(TMyEnum) - Low(TMyEnum) + 1;
Aber wie Apollonius schon erwähnte geht das nur wenn zwischendurch keine Werte "fehlen".

also bei den einfachen Varianten
Delphi-Quellcode:
Anzahl := High(TMyEnum) - Low(TMyEnum) + 1;
// oder
Anzahl := High(TMyEnum) + 1; // da Low(TMyEnum) per Defult 0 ist
Und für den Rest gibt es keine Möglichkeit, da nirgend's gespeichert wird welche Werte belegt sind und welche nicht.

Du kannst dir höchstens eine Konstante definieren, wo du selber die vorhandenen Werte einfügst und kannst dieses dann zählen/prüfen lassen.

Bernhard Geyer 9. Dez 2007 13:40

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Sorry quatsch. Schau gerade noch ...

Ares 9. Dez 2007 13:44

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Hallo!

Vielen Dank für den Tipp, die for-Schleife funktioniert prima. Kann man das auch in eine allgemeine Funktion umwandeln, die für einen beliebigen Aufzählungstyp die Anzahl der Elemente ermittel?

Delphi-Quellcode:
function EnumLength(Enum: TClass): Integer;
var i: TClass;
begin
  result := 0;
  try
    for i:=Low(Enum) to High(Enum) do
      inc(result);
  except

  end;
end;
Dies funktioniert leider nicht, weil i in der for-Schleife ein Ordinaltyp sein muss. Ich weiß allerdings nicht wie man einen Ordinaltyp angibt. Etwas wie i: TOrdType; gibt es nicht...

EDIT:
Ok, ich habe gerade erste die weiteren Antworten gesehen. Ich verwende nur Aufzählungstypen, bei denen ich die Ordinalwerte nicht selber vorgebe. Der Spezialfall, dass "zwischendurch Werte fehlen" kann hierbei also ignoriert werden. Für die Variante result := High(TOrdType)-1; fehlt mir auch noch das Wissen wie man korrekt einen Ordinaltyp angibt...

MrKnogge 9. Dez 2007 13:52

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
i muss vom typ integer sein.

Progman 9. Dez 2007 13:53

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
var i: Integer; !!
Ordinaltypen sind Integer, Char, Byte, Word etc.

Ares 9. Dez 2007 13:55

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Zitat:

Zitat von MrKnogge
i muss vom typ integer sein.

Das ist soweit ich weiß falsch. Die Schleifenvariable i muss "nur" ein Ordinaltyp sein (Integer ist ein solcher). Die Frage ist also gerade, wie ich die Funktion so deklariere, dass ein Ordinaltyp übergeben wird.

MrKnogge 9. Dez 2007 13:56

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Ich habe mich auf obiges Beispiel bezogen, war vermutlich nur ein kleiner fehler wenn man in Gedanken ist ...

Ares 9. Dez 2007 13:59

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Das Ganze müsste irgendwie so aussehen:

Delphi-Quellcode:
function EnumLength(Enum: Ordinaltyp): Integer;
var i: Ordinaltyp;
begin
  result := 0;
  try
    for i:=Low(Enum) to High(Enum) do
      inc(result);
  except

  end;
end;


ODER

function EnumLength(Enum: Ordinaltyp): Integer;
begin
  result:= High(Enum) + 1;
end;
In beiden Fällen muss ich wissen, was ich an Stelle von Ordinaltyp angeben muss.

MrKnogge 9. Dez 2007 14:00

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Wie bereits geschrieben, integer oder besser TMyEnum

Bernhard Geyer 9. Dez 2007 14:03

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Könnte man u.U. über die Unit TypeInfo und der RTTI etwas herausfinden?
Die Funktion GetEnumName hört sich doch gut an oder man geht über TypeInfo: PTypeInfo und dort über @T^.NameList. Aber aufgrund der fehlenden Doku in diesem Bereich (auch bei D6) ist es nicht so einfach zu verstehen was man dort alles machen könnte.

himitsu 9. Dez 2007 14:10

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
@Ares wie kommst du jetzt auf eine Klasse (TClass)? :shock:

i muß den selben Typ wie der Enumerator haben, also TMyEnum (oder wie er bei dir heißt.)

Try-Except ist hierbei unnötig, wo sollte auch eine Exception auftreten?

und jetzt rate mal wie oft die For-Schleife durchlaufen wird ... genau "High-Low+1"-mal ... und da nur ein Inc drinsteht, wleches die Durchläufe zählt, kann man sich die Durchläufe doch auch gleich ausrechen :zwinker:



Delphi-Quellcode:
type
  TMyEnum = (meEins, meZwei, meDrei);
  TMyEnumEx = (mxEins=1, mxZwei=2, mxSechs=6);

const
  MyEnumEx: Set of TMyEnumEx = [mxEins, mxZwei, mxSechs];

procedure TForm1.Button1Click(Sender: TObject);
var
  i: TMyEnum;
  i2: TMyEnumEx;
  Zaehler1, Zaehler2, Zaehler3, Zaehler4, Zaehler5: Integer;
  S: String;
begin
  Zaehler1 := 0;
  for i := Low(TMyEnum) to High(TMyEnum) do
    Inc(Zaehler1);

  Zaehler2 := Ord(High(TMyEnum)) - Ord(Low(TMyEnum)) + 1;

  Zaehler3 := 0;
  for i2 := Low(TMyEnumEx) to High(TMyEnumEx) do
    Inc(Zaehler3);

  Zaehler4 := Ord(High(TMyEnumEx)) - Ord(Low(TMyEnumEx)) + 1;

  Zaehler5 := 0;
  for i2 := Low(TMyEnumEx) to High(TMyEnumEx) do
    if i2 in MyEnumEx then
      Inc(Zaehler5);

  S := Format('TMyEnum - For: %d'#13#10
    + 'TMyEnum - Math: %d'#13#10
    + 'TMyEnumEx - For: %d'#13#10
    + 'TMyEnumEx - Math: %d'#13#10
    + 'TMyEnumEx - Const: %d',
    [Zaehler1, Zaehler2, Zaehler3, Zaehler4, Zaehler5]);
  Application.MessageBox(PChar(S), '');
end;

Ares 9. Dez 2007 14:13

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Zitat:

Zitat von MrKnogge
Wie bereits geschrieben, integer.

Sorry, aber das verstehe ich nicht. Oder vielleicht reden wir an einander vorbei?

Folgendes würde ich gerne realisieren:

Delphi-Quellcode:
type
  TMyEnum = (meEins, meZwei, meDrei);
  ...
 
  int := EnumLength(TMyEnum);
  // --> EnumLength liefert 3 zurück
Hierfür muss ich der Funktion EnumLength jeden beliebigen Aufzählungstyp übergeben können. Wenn ich die Funktion mit i: integer Verwende erhalte ich die Meldung "Inkompatible Typen", weil i vom Typ Integer und Enum vom Typ TClass ist. Hierbei ist noch zu beachten, dass TClass natürlich auch falsch ist. Enum müsste vom Typ TAufzählungstyp sein. Nur weiß ich eben nicht wie ich dies angeben kann.

himitsu 9. Dez 2007 14:37

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
eine allgemeine Funktion ist nicht mögilich, denn:

- Enumeratoren verfügen über keine Typeninformationen
- High/Low wird vom Compiler durch Konstanten erstetzt ... dieses sind keine Funktionen

also selbst wenn es möglich wäre alle Enum-Typen an eine Funktion zu übergeben, dann wären innerhalb der Funktion keine Informationen für High/Low verfügbar.
Heißt EnumLength kann immer nur für einen Typ erstellt werden!

allerdings liefert hier EnumLength die Werte für den Typ Integer und nicht für TMyEnum :warn:
Also: dieses funktioniert nicht.
Delphi-Quellcode:
function EnumLength(Enum: Integer): Integer;
var i: Integer;
begin
  result := 0;
  for i := Low(Integer) to High(Integer) do
    inc(result);
end;


Var X: TMyEnum;
  Y: TMyEnum2;
EnumLength(Integer(X));
EnumLength(Integer(Y));

Zusammengefasst:
direkte Lösungen wurden alle schon aufgezählt (Zusammenfassung siehe Beitrag #14)

allgemeine Funktionen sind nicht möglich.

Apollonius 9. Dez 2007 14:41

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Zitat:

Enumeratoren verfügen über keine Typeninformationen
Lass dich bloß nicht bei solchen Aussagen erwischen. GetEnumName und GetEnumValue aus der Unit TypInfo nehmen Parameter vom Typ PTypeInfo entgegen, die genau diese Typeninformationen des Aufzählungstypen sind.

himitsu 9. Dez 2007 14:51

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
TypeInfo(TMyEnumEx)
Zitat:

Zitat von DelphiCompiler
Typ 'TMyEnumEx' besitzt keine Typinformationen

ergo:
Delphi-Quellcode:
Var P: PTypeInfo;

P := TypeInfo(TMyEnumEx); // geht nicht !!!

Name := GetEnumName(P);
Value := GetEnumValue(P);

Progman 9. Dez 2007 14:58

Re: Anzahl der Elemente eines Aufzählungstyps ermitteln
 
Ich glaube, einen direkten Typ für sowas gibts gar nicht, aber
Delphi-Quellcode:
var int: Integer;
  ...
int := High(DeinEnumTyp) + 1;
erfüllt doch den gleichen Zweck.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:32 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-2025 by Thomas Breitkreuz