![]() |
Delphi-Version: XE
Verständnisproblem: Globale, gruppierte Konstanten
Ich benötige in meiner Software regelmäßig gewisse Werte, die stets gleich bleiben sollen und sich in einer Ini Datei speichern lassen.
Die Werte sollten zudem irgendwie gruppiert sein, damit man damit leichter arbeiten kann (Autovervollständigung, Parameter-Eingrenzung). So eine Liste ist zwar oft sehr praktisch und per
Delphi-Quellcode:
lässt sich auch ein speicherbarer Wert ableiten, aber wenn ich die Liste später irgendwann verändere, ist es unmöglich, neue Werte zwischenrein zu setzen, da sich sonst die Zählnummer ändert.
Ord()
Delphi-Quellcode:
TTier = (tiHund, tiKatze, tiMaus)
Um den Werten speicherbare Zahlen zuzuordnen, dachte ich stattdessen an sowas:
Delphi-Quellcode:
Leider bin ich mir noch etwas unschlüssig, ob Records wirklich der beste Weg dafür sind oder ob es eine noch bessere Möglichkeit gibt.
TTier = record
const HUND = 0; const KATZE = 12; const MAUS = 5; end; Ich weiß, dass ich das auch als Klasse/Objekt lösen kann. Aber irgendwie fände ich es seltsam, für jede Wertegruppe ein globales Objekt zu erzeugen, das nur konstante Werte bereithält!? Schön wäre es z.B., wenn man damit auch die Parameter-Typen in Funktionen festlegen könnte. Also etwa sowas:
Delphi-Quellcode:
function GetTiername(tn: TTier): String;
Mit Aufruf:
Delphi-Quellcode:
s := GetTiername(TTier.HUND);
Das geht aber natürlich nicht, weil dann ein vollständiges Record und nicht ein einfacher Wert erwartet wird. Ändert man den Parameter in Integer, geht der Aufruf, aber die Funktion lässt sich dann natürlich auch mit allen anderen Integern und nicht nur den TTier-Werten aufrufen. Zudem weiß ich leider nicht, ob es OK ist, direkt auf die Record-Werte zuzugreifen (
Delphi-Quellcode:
) oder ob man das besser erst instanzieren sollte (
TTier.HUND
Delphi-Quellcode:
)
var Tier: TTier; {...} Tier.HUND
Ich würde mich freuen, wenn Ihr mir hier etwas auf die Sprünge helfen würdet. Danke! |
AW: Verständnisproblem: Globale, gruppierte Konstanten
Zitat:
Diese RTTI-Daten kann man kann auch problemlos verwenden, um damit die Autovervollständigung zu füttern. Constanten stehen nicht in der RTTI, also lassen sie sich nicht automatisch auslesen und du bräuchstest somit eine manuell erstellte Liste/Array mit den Werten, um sie in der Autovervollständigung nutzen zu können. (siehe die TColor-Konstanten) Diese Liste kann auch über eine Registrierungsfunktion zur Laufzeit (z.B. beim Programmstart) gefüllt werden. |
AW: Verständnisproblem: Globale, gruppierte Konstanten
Zitat:
Zitat:
Meinst Du ich soll das so ähnlich machen?
Delphi-Quellcode:
type
TTier = -$7FFFFFFF-1..$7FFFFFFF; const tiKatze = TTier($00000C); |
AW: Verständnisproblem: Globale, gruppierte Konstanten
Keine Sorge, selbst wenn man die neue erweiterte RTTI fast komplett deaktiviert (was möglich ist), dann funktioniert das immernoch, da diese Funktion auf die alte RTTI aufbaut, welche es schon praktisch immer gibt, da sie von der VCL (FormDesigner) rege verwendet wird.
![]() GetEnumName und SetToString (Unit TypInfo), bzw. besser und vorallem (typ)sicherer hinter den Generics versteckt. Und ich meinte das Colors-Array, welches sich aktuell in UIConsts versteckt und das z.B. von ColorToString verwendet wird. Natürlich ist dieses Array fest, so daß man (eigentlich) keine eigenen TColor-Konstanten in den DFM-Loader einschleußen kann. |
AW: Verständnisproblem: Globale, gruppierte Konstanten
Wieso eine Ini-Datei, wenn es sich doch angeblich um immer gleichbleibende Konstanten handelt? Konstanten wird gewöhnlich ein Wert im Programmcode zugewiesen. Weist du Variablen Werte aus einer Ini-Datei zu, sind das keine Konstanten, sondern eben Variablen, auch wenn diese im gesamten Programmverlauf weitgehend konstant bleiben (sollen), wie z.B. ein Datenbank-Pfad oder der Benutzername usw. Deshalb unterscheidet Delphi doch Konstanten und Variablen, deren Deklaration mit unterschiedlichen Tokens eingeleitet wird: Const und Var.
|
AW: Verständnisproblem: Globale, gruppierte Konstanten
Zitat:
|
AW: Verständnisproblem: Globale, gruppierte Konstanten
Das was du meinst ist wohl ein
![]() Ein Beispiel (zwar PHP sollte aber aussagekräftig genug sein) für Währungen findest du unter ![]() |
AW: Verständnisproblem: Globale, gruppierte Konstanten
Zitat:
|
AW: Verständnisproblem: Globale, gruppierte Konstanten
Du kannst auch sowas machen:
Delphi-Quellcode:
TTier = (tiHund = 1, tiKatze = 27, tiMaus = 15, ...)
|
AW: Verständnisproblem: Globale, gruppierte Konstanten
Zitat:
In der deutschen Sprache sind Interpretationen Gott-Sei-Dank erlaubt. Ich definiere eine 'Konstante' übrigens als Wert, der im Anwendungskontext nicht verändert wird. Diese Interpretation lässt mir die Freiheit, in einer Spezifikation den Terminus 'Konstante' zu verwenden, ohne gerichtlich einklagbar darauf drängen zu müssen, das dieser Wert im Code auch als 'CONST' deklariert werden muss. Es reicht, wenn er während des Lebenszyklus der Anwendung nicht veränderbar ist, und das schließt initiales Laden aus. Gleichzeitig verbaue ich mir damit nicht die Möglichkeit des initialen Ladens. Aber wenn Du dich dran reibst, dann wende dich an Emba:
Delphi-Quellcode:
Im Übrigen bin ich auch für korrekte Terminologie, aber nur, wenn es um wichtige Dinge geht. Auch kann ich verstehen, das in der reinen Sprachenlehre eine Konstante nicht immer eine Konstante ist. Aber dann ist sie eigentlich auch keine Variable, denn verändert wird sie nicht (nur initialiert).
Const
IAmNotAConstant : Integer = 3; begin {$J+} IAmNotAConstant := 4; // Verbooooten !!!1!!!!11!!!EINS!!!11!!ELF!!! Zitat:
Delphi-Quellcode:
Diese Unit bindest Du einfach immer dann ein, wenn Du Zugriff auf die Applikationskonstanten benötigst. Du hast hier dann alles, was Du brauchst. Damit wäre deine erste Vorgabe erfüllt:
Type
Unit ApplicationSettings; Interface Type TApplicationContext = Class private class var fMySetting : string; class var fSomeOtherValue : Integer; class procedure Load(); public Class property MySetting : String read fMySetting; class property SomeOtherValue : Integer read fSomeOtherValue; end; ... implementation ... initialization TApplicationContext.Load(); end. Zitat:
Ich würde meine TTier-Klasse wie folgt umsetzen, und dabei die von Sir Rufo vorgeschlagenen value objects einsetzen. Die Methode 'GetTierName' gehört dann zum Tier (OOP) und ist keine isolierte Funktion (PP)
Delphi-Quellcode:
Und damit solltest Du alle deine Wünsche umsetzen können, denn eine Katze ist ein Tier, konstant, die Id ist Perlsau-konform (sofern man die Datei nicht verändert, siehe Heraklit) und deine Tiere können um Methoden und Eigenschaften erweitert werden, was bei einem Enum nicht geht. Ich persönlich halte auch nicht viel von RTTI-Geraffel im Hintergrund.
Type
TTier = class private fID: Integer; fName : String; class var fKatze: TTier; class var fHund: TTier; class procedure Load; constructor Create (aID : Integer; Name : String); public property ID : Integer read fID; property Name : String read fName; class property Hund : TTier Read fHund; class property Katze : TTier Read fKatze; end; { TTier } constructor TTier.Create(aID: Integer); begin fID := aID; end; class procedure TTier.Load; begin // Natürlich wird hier aus einer Datei/Registry/Datenbank geladen fHund := TTier.Create(3,'Hund'); fKatze := TTier.Create(4,'Mitzekatze'); end; initialization TTier.Load; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 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