1. Die einzelnen Typen sollen sicher und eindeutig sein.
Gemeint ist, das, wenn man das ganze als Parameter an eine Methode übergibt, keine andere Maßeinheit
übergeben werden kann
Beispiel:
Procedure TuWas(const a:gramm);
Wenn versucht wird, hier Kilogram zu übergeben, soll der Compiler meckern.
Vorweg:
Ich empfehle eine kurze Recherche bei Wikipedia zu Maßeinheiten, Vorsätzen und Einheitensystem zur Auffrischung.
Möglich wäre auch, dass du dir mal anschaust wie das die Delphi
RTL für System.TimeSpan.TTimeSpan regelt.
Es ist mir beim Überfliegen dieses und des anderen Threads nicht ganz klar geworden, ob das mit den Gewicht nur ein Beispiel/Analogie ist oder du wirklich mit Gewichtsangaben arbeiten musst.
Nehmen wir mal an, es geht wirklich um Gewicht, also du willst die physikalische Maßeinheit für die Masse in einer bestimmten Gravation beziffern:
Gramm, Kilogramm, Tonne (1000 kg), Kilotonne (1000 * 1000 kg) sind
keine verschiedenen Maßeinheiten.
Es bezieht sich immer auf ein und dasselbe mit verschiedenen Vorsätzen für Maßeinheiten.
Die SI-Basiseinheit für Masse ist das Kilogramm. Ein Gramm ist ein Tausendstel Kilogramm. Soweit bekannt, nix neues.
Schaffe dir einfach einen einzigen konkreten Basisdatentyp, bspw. mit Gramm und gebe ihm die entsprechenden Methoden.
Delphi-Quellcode:
type
TKilogramm = type UInt64;
TTonne = type UInt64;
TKilogrammHelper = record helper for TKilogramm
function ToString: string;
end;
TTonneHelper = record helper for TTonne
function ToString: string;
end;
TGramm = type Double;
TGewicht = record
strict private
FDasRichtigeGewichtInGrammAlsFliesskommazahl: TGramm;
// Warum Fliesskomma? Vielleicht willst du auch mal Milli- und/oder Mikrogramm verarbeiten.
// Man kann natürlich auch mit einen UInt32 oder UInt64 als Basis arbeiten, dann muss das aber im Vorfeld klar sein, welche die kleinste Größe ist.
// Bei einen Kuchenrezept bspw. ist höchstwahrscheinlich die kleinste Gewichtsangabe sowas wie "eine Prise Salz/ein halbes Gramm".
private
// ggf. mit richtigen Gettern und Settern versehen
property RawValue: TGramm read FDasRichtigeGewichtInGrammAlsFliesskommazahl write FDasRichtigeGewichtInGrammAlsFliesskommazahl;
public
class function Add(const A, B: TGewicht): TGewicht; static;
function AsKilogramm: TKilogramm;
// Hier kommen nur sinnvolle Werte größer null bei raus, wenn die interne Variable vor dem Komma mehr als 1000 groß ist.
function AsTonne: TTonne;
// Hier kommen nur sinnvolle Werte größer null bei raus, wenn die interne Variable vor dem Komma mehr als 1000 * 1000 groß ist.
end;
implementation
{ TGewicht }
class function TGewicht.Add(const A, B: TGewicht): TGewicht;
begin
Result.RawValue := A.RawValue + B.RawValue;
end;
function TGewicht.AsKilogramm: TKilogramm;
begin
Result := Round(RawValue / 1000);
end;
function TGewicht.AsTonne: TTonne;
begin
Result := Round(RawValue / 1000 * 1000);
end;
{ TKilogrammHelper }
function TKilogrammHelper.ToString: string;
begin
end;
{ TTonneHelper }
function TTonneHelper.ToString: string;
begin
end;