Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Array [Auszählungstyp] of irgendwas? (https://www.delphipraxis.net/178091-array-%5Bauszaehlungstyp%5D-irgendwas.html)

Mikkey 17. Dez 2013 09:40

Delphi-Version: 7

Array [Auszählungstyp] of irgendwas?
 
Ich habe eine Typdefinition:

Delphi-Quellcode:
TEnum = (Anfang = 1, Mitte = 3, Ende = 5);
und ein String-Array, in denen die Werte des Typs beschrieben werden:

Delphi-Quellcode:
g_TEnumNames = Array[TEnum] of String =
  ('Anfang',
   '',
   'Mitte',
   '',
   'Ende');
Wenn ich die Leerstring-Einträge weglasse, mault der Compiler (Anzahlen stimmen nicht überein). Warum?

Noch extremer wird es (finde ich jedenfalls), wenn ich über den Typ iteriere:

Delphi-Quellcode:
pos: TEnum;
...
for pos := Low(TEnum) to High(TEnum) do
  TuIrgendwasMit(pos, g_TenumNames[pos]);
Die Schleife wird fünfmal durchlaufen, obwohl der Typ nur mit drei Werten definiert ist.

Gibt es eine saubere Methode, einen Typ aus drei Werten tatsächlich nur aus drei Werten bestehen zu lassen (und trotzdem eine selbstgewählte Numerierung beizubehalten)?

Furtbichler 17. Dez 2013 09:50

AW: Array [Auszählungstyp] of irgendwas?
 
Die einzige Möglichkeit, die mir einfällt, wäre:
Delphi-Quellcode:
Type
  TEnum = (Anfang = 1, Mitte = 3, Ende = 5);

Function NextEnum (e: TEnum) : TEnum;
Begin
  case e of
    Anfang : Return Mitte;
    Mitte : Return Ende;
    else Raise EInvalidArgument.Create; // K.A. wie das in Delphi heißt.
  End
End;
...

e := Anfang;
While e <> Ende Do begin
  e :=NextEnum(e);
end;
Anders würde der Compiler eine Sukkzessor-Funktion auf TEnum auch nicht umsetzen.

Wieso willst Du den Enum-Elementen eigentlich nicht fortlaufende Werte geben? Wenn Du gleichzeitig iterieren musst, könntest Du doch eine Abbildungsfunktion schreiben, also z.B. so:
Delphi-Quellcode:
Type
  TEnum := (Anfang, Mitte, Ende);

Const
  EnumWerte : Array [TEnum] Of Integer = (1,3,5);
  EnumNamen : Array [TEnum] Of String = ('Anfang','Mitte','Ende');

himitsu 17. Dez 2013 09:54

AW: Array [Auszählungstyp] of irgendwas?
 
Ist auch richtig so, denn ein Enum hat nunmal nur einen Anfang und ein Ende ... er kennt kein "das dazwischen gibt es nicht"


Und weißt du was noch schön ist?
Bei Enums mit vorgabewerten, wird keine RTTI über die Namen angelegt, weswegen du auch nicht die Enum-Werte in ihre "Strings" via RTTI übersetzen kannst
und somit auch da nicht prüfbar ist, was es gibt.

Namenloser 17. Dez 2013 09:55

AW: Array [Auszählungstyp] of irgendwas?
 
Also in neueren Delphis gibt es ja for-in-Schleifen, damit sollte – vermutlich – zumindest das Problem mit dem Iterieren gelöst sein.

[roter Kasten] Denke auch, die zweite Variante wäre am besten.

himitsu 17. Dez 2013 09:56

AW: Array [Auszählungstyp] of irgendwas?
 
Delphi-Quellcode:
Type TEnum = (Anfang, Mitte, Ende);
läßt sich via Delphi-Referenz durchsuchenGetEnumName (Hier im Forum suchenGetEnumName) in einen String übersetzen, welcher zufälig genau deinem Array entspricht.

Also zusammen mit
Delphi-Quellcode:
Const EnumWerte : Array [TEnum] Of Integer = (1,3,5);
.



Bei neueren Delphis könnte man die Werte auch via Attribut an die Typ-Definition hängen
und man könnte da auch andere/alternative "Namen" via Attribut angeben. (wenn man nicht GetEnumName nimmt, sondern es dort selber aussliest)

Mikkey 17. Dez 2013 10:16

AW: Array [Auszählungstyp] of irgendwas?
 
Vielen Dank erstmal für die Anregungen. Ich werde mal versuchen, ob ich mit "GetEnumName" weiterkomme (Namen wären mir auch lieber als die Nummern).

Ansonsten finde ich Furtbichlers zweiten Vorschlag praktikabel, das wird "Plan B"

himitsu 17. Dez 2013 10:16

AW: Array [Auszählungstyp] of irgendwas?
 
Und nochmal ein kleines Beispiel, zu dem "warum" es nicht geht.
Das ist wie beim Boolean, welcher auch nicht "nur" zwei Zustände kennt -> http://www.delphipraxis.net/178082-v...lean-zahl.html

Delphi-Quellcode:
type
  TMyEnum = (Anfang = 1, Mitte = 3, Ende = 5);
 
var
  MyEnum: TMyEnum;
   
MyEnum := TMyEnum(2); // hier ginge auch 0 bis 255 (oder größer, jenachdem wie $MINENUMSIZE definiert und wie groß der größte Wert in der Debinition ist)
 
Case MyEnum of
  Anfang: ShowMessage('Anfang ' + IntToStr(Ord(MyEnum)));
  Mitte: ShowMessage('Mitte ' + IntToStr(Ord(MyEnum)));
  Ende: ShowMessage('Ende ' + IntToStr(Ord(MyEnum)));
  Else ShowMessage('blubb ' + IntToStr(Ord(MyEnum)));
End;

Mikkey 17. Dez 2013 10:59

AW: Array [Auszählungstyp] of irgendwas?
 
@Himitsu:

Das ist der Grund weshalb bei der Geschichte das Zweifeln anfängt.

Da ist eine Variable vom Typ T. Bisher bin ich (in Analogie zu C#) davon ausgegangen, dass die Variable wirklich vom Typ T ist - Der "else" (bzw. "default:") würde von einem Quellcodeanalyzer bemängelt werden, weil er nie ausgeführt werden könnte.

Bedeutet das nun, dass eine Methode, der ein T-Parameter übergeben wird, nun überprüfen muss, ob der Parameter wirklich ein T ist?

Der GetEnumName funktioniert leider in meinem Delphi nicht, (eben weil keine RTTI für den Enum-Typ vorhanden ist).

@ Namenloser: Roter Kasten?

@Furtbichler:
Plan B funktioniert (logisch).

Der Grund für die Numerierung ist der, dass die Klassen, in denen der Typ enthalten ist in eine Datenbank persistiert werden und es denkbar ist, dass es eine Erweiterung gibt. Andererseits möchte ich eine Kontrolle über die Reihenfolge der Werte behalten.

Aussehen tut es jetzt so:

Delphi-Quellcode:
g_EreignisTypNummer: Array[TEreignisTyp] of Integer = (1,2,3,4,10,11,12,13,14);
g_EreignisTypName: Array[TEreignisTyp] of String = (...);
...
  for ereignis := Low(TEreignisTyp) to High(TEreignisTyp) do begin
    ereignisNr := g_EreignisTypNummer[ereignis];
    TuIrgendwasMit(ereignis, ereignisNr, EreignisTypName[ereignis]);
  end;
...
  query.Parameters.ParamValues['EreignisTyp']:= g_EreignisTypNummer[m_EreignisTyp];
Nochmals vielen Dank

sx2008 17. Dez 2013 11:03

AW: Array [Auszählungstyp] of irgendwas?
 
Wenn du unbedingt den Enumwerten eine Zahl zuordnen musst dann geht das so:
Delphi-Quellcode:
TEnumErrors = (NOERROR=0, FILEERROR=104, NETERROR=200, ...);

TErrorInfo = record
  err: TEnumErrors;
  txt: String;
end;

const
  ErrorInfo: array[0..2] of TErrorInfo = (
  (err:NOERROR; txt:"kein Fehler"),
  (err:FILEERROR; txt:"Dateifehler"),
  (err:NETERROR; txt:"Netzwerkfehler")
);
Um jetzt von einem TEnumError zu der Beschreibung zu kommen verwendet man eine For-Schleife über das Array ErrorInfo und holt sich den passenden txt raus.
Der Code dazu spare ich mir -> Hausaufgabe.
Man kann den Record auch um weitere Infos erweitern wie z.B. die Schwere des Fehlers.

Namenloser 17. Dez 2013 11:06

AW: Array [Auszählungstyp] of irgendwas?
 
Zitat:

Zitat von Mikkey (Beitrag 1240104)
@ Namenloser: Roter Kasten?

Wenn man in der DP einen Beitrag abschickt und währenddessen bereits ein neuer Beitrag gepostet wurde, bekommt man einen roten Kasten als Warnmeldung.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:35 Uhr.
Seite 1 von 2  1 2      

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