![]() |
AW: Maßeinheiten als Typen
Zitat:
Wird eine Formel anders, wenn du statt mit 100kg einfach mit 0,1t rechnest? Oder würde die Formel nicht eher so aussehen
Delphi-Quellcode:
Oder um bei deinem Beispiel zu bleiben
class operator TDuration.Divide( const a: TLength; const b: TDuration ): TSpeed;
begin Result := TSpeed.FromMetersPerSecond( a.Meters / b.Seconds ); end;
Delphi-Quellcode:
Warum sollte es eine gesonderte Rolle spielen ob ich den Wert in Tonnen oder Kilogramm übergeben habe? In der Berechnung werden die korrekten Einheiten verwendet und nur das zählt.
function Tuwas( const gewichtA, gewichtB : TWeight ): Currency;
begin // Preis für A = 20 Euro pro Kilogramm // Preis für B = 30 Euro pro Gramm Result := 20 * gewichtA.Kilograms + 30 * gewichtB.Grams; end; |
AW: Maßeinheiten als Typen
hmm...ok..mit Type of macht es zumindest schon mal keine Probleme bei überladenen Methoden.
Aber wie bastel ich dann entsprechende Operatoren ? |
AW: Maßeinheiten als Typen
Ich würde sagen, Du machst es Dir zu schwer.
Bei uns gibt es die gleiche Problematik. Allerdings versuchen wir das nicht innerhalb der Verarbeitung abzufangen. Es gbt für jeden "Einheistfall" einen Basistypen. Bei uns für Länge, Flächen, Volumen, Gewicht, Winkel etc. Der Basistyp muss halt Deinen gesamten Wertebereich der jeweiligen Einheit abfangen. Umgewandelt wird nur zur Anzeige oder bei Lesen/Schreiben...... Das vereinfacht innerhalb des Programmes die ganze Rechnerei. Wir haben Edits die den Basistyp bekommen und je nach Einstellung das in der jeweiigen Einheit anzeigt und annnimmt. Alles einfach Testbar. |
AW: Maßeinheiten als Typen
Unter Verwendung der Units System.ConvUtils und System.StdConvs kann man da recht einfach was zaubern:
Delphi-Quellcode:
Natürlich kannst du dir auch selbst deine Einheiten und Konvertierungen erstellen, aber es gibt halt mit den oben genannten Units schon einen vorgefertigten Mechanismus dafür.
type
TGramm = type Double; TKilogramm = type Double; TWeight = record private FConv: TConvType; FValue: Double; public constructor Create(AValue: Double; AConv: TConvType); class operator Implicit(A: TWeight): TGramm; overload; class operator Implicit(A: TGramm): TWeight; overload; class operator Implicit(A: TWeight): TKilogramm; overload; class operator Implicit(A: TKiloGramm): TWeight; overload; property Conv: TConvType read FConv write FConv; property Value: Double read FValue write FValue; end; constructor TWeight.Create(AValue: Double; AConv: TConvType); begin FValue := AValue; FConv := AConv; end; class operator TWeight.Implicit(A: TWeight): TGramm; begin Result := Convert(A.Value, A.Conv, muGrams); end; class operator TWeight.Implicit(A: TGramm): TWeight; begin Result := TWeight.Create(A, muGrams); end; class operator TWeight.Implicit(A: TWeight): TKilogramm; begin Result := Convert(A.Value, A.Conv, muKilograms); end; class operator TWeight.Implicit(A: TKiloGramm): TWeight; begin Result := TWeight.Create(A, muKilograms); end; Das Konvertieren geht dann über ein Cast auf TWeight:
Delphi-Quellcode:
procedure TuWas(const Value: TGramm); overload;
var K: TKiloGramm; begin K := TWeight(Value); Writeln(Format('%1.3f g = %1.3f Kg', [Value, K])); end; procedure TuWas(const Value: TKiloGramm); overload; var K: TGramm; begin K := TWeight(Value); Writeln(Format('%1.3f Kg = %1.3f g', [Value, K])); end;
Delphi-Quellcode:
var
A: TKiloGramm; B: TGramm; C: TTonnen; begin A := 50; B := 1500; TuWas(A); TuWas(B); TuWas(C); // Fehlermeldung: Doppeldeutiger überladener Aufruf von 'TuWas' end; |
AW: Maßeinheiten als Typen
@Schokohase
Und wie stellst du sicher, das an Tuwas keine Tonnen übergeben werden, weil z.B. kein Preis dafür definiert ist ? @Uwe Naja...im Prinzip ists das gleiche, wenn ich alles in einen Typen reinschiebe. Außer das ich alles in einem Typen hab (der verdammt groß wird) hätte ich nicht wirklich was gewonnen. Die ganze Operator-Kombinationen müsst ich ja genauso implementieren und entsprechend testen. |
AW: Maßeinheiten als Typen
Zitat:
Wenn du davon 3 Trillionen Tonnen haben möchtest, dann lasse ich mir über den Typen das Gewicht in Kilogram geben und multipliziere das mit den 20 Euro oder ich lasse mir das über den Typen in Gramm geben und multipilziere das mit den 30 Euro (je nachdem). |
AW: Maßeinheiten als Typen
Ich glaub ich hab dich da schon richtig verstanden. Klar kann ich das umrechnen (von T in kg oder g). Wenn es aber keine T gibt (aus welchen Gründen auch immer), dann kann das Tuwas nicht unterscheiden.
|
AW: Maßeinheiten als Typen
Ich würde sagen, dass dann die Unterscheidung nicht mehr im Verantwortungsbereich von TuWas() liegt, sondern bereits vorher erledigt werden muss. Nämlich direkt nach der Eingabe in der Glue-Logic des Forms, weil das der einzige Zeitpunkt sein sollte, zu dem diese Unterscheidung Sinn ergibt. Vor allem weil ja vermutlich erst über die Beschriftung im Formular deutlich wird welche Einheit letztlich eingegeben wird. Die Geschäftslogik sollte das nicht mehr interessieren dürfen. Das wäre so meine Interpretation zumindest.
|
AW: Maßeinheiten als Typen
Zitat:
Ist es vielleicht so, dass es unterschiedliche Preise für kg und Tonnen gibt und du musst deshalb eine Unterscheidung machen. :glaskugel: Hat irgendwie etwas von dem ![]() |
AW: Maßeinheiten als Typen
Zitat:
Ansonsten nimmt man einen Typen für eine Einhait, dieser speichert den Wert so wie der als SI Einheit definiert ist (Gewicht-> Kilogramm, Länge->Meter, Temeraturdifferenz->Kelvin, usw.) und schafft sich einfache Zugriffsmöglichkeiten um diese dann beliebig umzurechnen. Also
Delphi-Quellcode:
ergibt dann die Zahl 1000000.
TWeight.FromTons(1).Grams
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:25 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