Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   System.Enum.IsDefined in nicht-net-Projekten? (https://www.delphipraxis.net/202969-system-enum-isdefined-nicht-net-projekten.html)

DieDolly 30. Dez 2019 17:22

System.Enum.IsDefined in nicht-net-Projekten?
 
Gibt es ein Pendant von System.Enum.IsDefined() auch für nicht-net-Projekte?
Ich möchte meinen Code verkürzen und da würde mir IsDefined etwas bei helfen.

Delphi-Quellcode:
 if (Ord(MyValue) < 0) or (Ord(MyValue) > Ord(High(TMyEnum))) then

Da da oben könnte ich auch in eine Funktion packen. Aber vielleicht gibt es j schon was Fertiges.

Der schöne Günther 30. Dez 2019 17:41

AW: System.Enum.IsDefined in nicht-net-Projekten?
 
Solange man nicht anfängt blanke Zahlen in Enum-Variablen zu quetschen sehe ich in Delphi die Notwendigkeit dafür noch nicht ganz.

Deine Bedingung prüft nur ob die Zahl zwischen 0 und dem höchsten ordinalen Enum-Wert ist. Das Enum.IsDefined(..) in .NET prüft ob der übergebene String oder Ordinalwert für die Enumeration gültig ist. Hast du beispielsweise ein Enum
Delphi-Quellcode:
TEnum = (uno = 4, dos = 8, tres = 16);
und quetscht da eine 5 rein würde dein Code meinen das wäre ein völlig gültiger Wert.

DieDolly 30. Dez 2019 17:44

AW: System.Enum.IsDefined in nicht-net-Projekten?
 
Danke für die Erklärung. Sowas in der Art dachte ich mir schon.
Wäre hier also eine einfache Funktion besser?

Delphi-Quellcode:
function TEnumUtils.isDefined<T>(MyValue: T): Boolean;
begin
 Result := not((Ord(MyValue) < 0) or (Ord(MyValue) > Ord(High(T))));
end;

Der schöne Günther 30. Dez 2019 17:53

AW: System.Enum.IsDefined in nicht-net-Projekten?
 
Nochmal: Das klappt nur wenn du davon ausgehst dass dein Enum keine "Lücken" hat. Also alle Werte aufeinander folgen.

Hier spricht ein ehemaliger Delphi-Entwickler zur (fehlenden) Möglichkeit:
https://stackoverflow.com/a/1420649



PS: Spring4D hat da auch schon etwas, kann allerdings auch nicht mit "Lücken-Enums" umgehen:
https://bitbucket.org/sglienke/sprin...pas#lines-3654

DieDolly 30. Dez 2019 18:05

AW: System.Enum.IsDefined in nicht-net-Projekten?
 
Meine Enums haben keine Lücken, da ich diese Zuweisung 1, 2, 3 nicht benutze.

Delphi-Quellcode:
function TEnumUtils.isDefined<T>(MyValue: T): Boolean;
begin
 Result := not((Ord(MyValue) < 0) or (Ord(MyValue) > Ord(High(T))));
end;
scheint ohnehin nicht zu funktionieren leider. Enums sind so ein Thema bei mir.
Deinen Link gucke ich mir gleich mal an.



Was genau macht eigentlich dieses Guard.CheckEnum?
Delphi-Quellcode:
class procedure Guard.CheckEnum<T>(const argumentValue: T;
  const argumentName: string);
var
  intValue: Integer;
begin
  intValue := 0;
  Move(argumentValue, intValue, SizeOf(T));
  Guard.CheckEnum<T>(intValue, argumentName);
end;


===

Hier ist mein Ergebnis
Delphi-Quellcode:
class function TEnumUtils.IsDefined<T>(const Value: Integer): Boolean;
var
 data: PTypeData;
begin
 data := GetTypeData(TypeInfo(T));
 Result := (Value >= data.MinValue) and (Value <= data.MaxValue);
end;

class function TEnumUtils.IsDefined<T>(const Value: T): Boolean;
var
 i: Integer;
begin
 i := TEnumUtils.ToInteger<T>(Value);
 Result := TEnumUtils.IsDefined<T>(i);
end;

class function TEnumUtils.IsDefined<T>(const Value: string): Boolean;
begin
 Result := TEnumUtils.IsDefined<T>(TEnumUtils.GetValue<T>(Value, -1));
end;
Ich habe mir noch ein IsDefined mit String-Parameter deklariert, weil ich das zusammen mit meiner Ini-Klasse benötige.

TurboMagic 31. Dez 2019 11:19

AW: System.Enum.IsDefined in nicht-net-Projekten?
 
Über RTTI kann man sich zu einem Enumwert als Zahl den Enum Bezeichner besorgen.
Weiß auswendig nicht wie, aber evtl. wäre das ein Denkansatz, wennglcih sicher kein
super performanter...


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:08 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