Denn ich habe ja immer eine Kombination aus Wert+Einheit
Genau, es ist eine Kombination, die man z.B. auch so abbilden kann
Delphi-Quellcode:
TMassUnit = (Undefined, Gram, Kilogram, Milligram, Tonne);
TMass =
record
private
FValue: Extended;
// Wert
FUnit: TMassUnit;
// Einheit
public
constructor Create(AValue: Extended; AUnit: TMassUnit);
property Value: Extended
read FValue;
property &
Unit: TMassUnit
read FUnit;
private
function AsBaseUnit(): Extended;
function AsBaseNumericType(AUnit: TMassUnit);
public
property Grams: Extended
index TMassUnit.Gram
read AsBaseNumericType;
property Kilograms: Extended
index TMassUnit.Kilogram
read AsBaseNumericType;
property Milligrams: Extended
index TMassUnit.Milligram
read AsBaseNumericType;
property Tonnes: Extended
index TMassUnit.Tonne
read AsBaseNumericType;
end;
In diesem Record kann man jetzt problemlos die Rechenoperationen und Umrechnungen implementieren und man hat
einen Typen für das Gewicht.
Aber es ist immernoch zu kompliziert. Wieso nicht den Wert immer in der Basiseinheit speichern und beim Zuweisen bzw. Auslesen aus diesem umrechnen? Die von Dir gewählte Implementation hat höchstens den Vorteil, dass, wenn man in derselben Einheit schreibt und dann ausliest, keine Umrechnungstattfindet, also auch keine Rechenungenauigkeiten auftreten.
Letzteres ist ein nicht zu unterschätzendes Problem, wenn es auf Genauigkeit ankommt. Da wäre es evtl. sinnvoll, zum Speichern des Wertes statt eines Fließkommatyps einen Integer in einer Einheit zu verwenden, die klein genug ist, um alles notwendige abzubilden, z.B. 1 mg oder auch 1 ug (vorausgesetzt kleinere Massen interessieren nicht). Oder man kombiniert einen Integer mit einem dezimalen Exponenten. d.h. Bei Zuweisung von 1 mg speichert man 1 als Wert und -1000000 als Exponent. Liest man dann den Wert in g aus, erhält man 0.001.
twm