Closed SGStino closed 5 years ago
Take a look at my PR, #593. I am not sure if this is enough, but it's hopefully a start!
Hey, certainly a usefull addition, but wasn't entirely what i meant. Shouldn't have used a fixed constant as an example.
I mean something like combining some units in a formula resulting in a more complex intermediate.
MolarEnergy.FromJoulesPerMole(1) / Temperature.FromKelvins(1)
would result in the same unit as Avogadro's number, but doesn't look like its feasible at the moment.
Or another one: [J/(kg K)]
pecificEnergy.FromKilowattHoursPerKilogram(1) / Temperature.FromKelvins(1)
So writing formulas would usually boil back to taking the SI unit from the quantity object, running the formula, and trying to create a new unit quantity from the result.
Storing intermediates would be in the old way without typing, strongly or not.
Take for example a classic: Q = m.c. ΔT
Q would be representable as EnergyUnit
m as MassUnit
ΔT as TemperatureDeltaUnit
but specifying c would have to be in the SI unit, as it can't be represented (yet)?
While there are many different options here: some specify it as [kJ/(kg K)]
, some as [Kcal/(kg °C)]
, certain people would even use [btu/(lb°F)]
..
I've investigated how math.js solves this for example, and it seems upon first glance that they have baseunits: Mass, Length, Volume, Temperature, ...
And compounds like speed are basically an array with the base/primitive unit and the power.
For speed this would be [(unit: LengthUnit.Meters, power:1), (unit: TimeUnit.Seconds, power:-1)]
Comparing if it's the same unit would ofc be only possible at runtime, but would come down to a check of the units and the powers.
I wonder if this could be an approach for v5 perhaps? (or it's already in and I just completly overlooked it?) EDIT: I wonder if Units.NET could take the ValueTuple approach:
ICompoundUnit<U1,U2>
ICompoundUnit<U1,U2,U3>
ICompoundUnit<U1,U2,U3,U4>
….
ICompoundUnit<U1,U2,U3,U4,U6,U7,U8, URest>
Although i'm not sure how URest should work with the following, I guess once you get that far it should become just IDynamicUnit or something, and no more compile-time checking from there on.
for example:
IMassFlowUnit : ICompoundUnit<IMassUnit,IInverseUnit<ITimeUnit>>
This could really simplify the library and adding extra units could be done through inheritance? Operators overloads on interfaces could become possible in c#8 or higher so we can specify the arithmic purely on the interfaces. https://github.com/dotnet/csharplang/issues/192 https://github.com/dotnet/csharplang/issues/515
With the added language features it could come down to copying the dynamic approach of math.js to a more static language as c# 9 or 10.
I'm not sure how many operator overloads that would generate though, since ICompoundUnit<IMassUnit, IInvertedUnit<IMassUnit>>
should just revert to IUnitless?
There are certainly tons of things I haven't thought about, this is just an idea I had and thought to share :smiley:
Cool stuff, but also heavy to digest late in the evening :-)
We do have BaseDimensions
on all our quantities, so we can possibly do something similar to Math.js, but without the static typing as you observed.
I think maybe we can get some static typing out of it though, please look at my comment here. We seem to be onto the same idea: https://github.com/angularsen/UnitsNet/issues/515#issuecomment-450319160
Closing this in favor of #515, just to keep discussion in a single place.
I'm searching for something that can handle slightly more complex units like representing avogadro's number [J/(mol K)] etc.
This would mean that these compound units aren't strongly typed anymore so i'm not sure if this is the goal of this library?