You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚡ Prefer built-in conversions over extensibility for perf (#1049)
Co-authored-by: Andreas Gullberg Larsen <[email protected]>
Fixes#1069
Per @lipchev's comments in #1023, I decided to add the local conversion method back (as private ```TryToUnit```). This will allow better performance for auto-generated conversions before falling back to the extensibility points.
/// Converts this {_quantity.Name} to another {_quantity.Name} using the given <paramref name=""unitConverter""/> with the unit representation <paramref name=""unit"" />.
950
+
/// Converts this <see cref=""{_quantity.Name}""/> to another <see cref=""{_quantity.Name}""/> using the given <paramref name=""unitConverter""/> with the unit representation <paramref name=""unit"" />.
950
951
/// </summary>
951
952
/// <param name=""unit"">The unit to convert to.</param>
952
953
/// <param name=""unitConverter"">The <see cref=""UnitConverter""/> to use for the conversion.</param>
953
954
/// <returns>A {_quantity.Name} with the specified unit.</returns>
954
955
public {_quantity.Name} ToUnit({_unitEnumName} unit, UnitConverter unitConverter)
955
956
{{
956
-
if (Unit == unit)
957
+
if (TryToUnit(unit, out var converted))
957
958
{{
958
-
// Already in requested units.
959
-
return this;
959
+
// Try to convert using the auto-generated conversion methods.
960
+
return converted!.Value;
960
961
}}
961
962
else if (unitConverter.TryGetConversionFunction((typeof({_quantity.Name}), Unit, typeof({_quantity.Name}), unit), out var conversionFunction))
962
963
{{
963
-
// Direct conversion to requested unit found. Return the converted quantity.
964
-
var converted = conversionFunction(this);
965
-
return ({_quantity.Name})converted;
964
+
// See if the unit converter has an extensibility conversion registered.
// Direct conversion to requested unit NOT found. Convert to BaseUnit, and then from BaseUnit to requested unit.
969
+
// Conversion to requested unit NOT found. Try to convert to BaseUnit, and then from BaseUnit to requested unit.
970
970
var inBaseUnits = ToUnit(BaseUnit);
971
971
return inBaseUnits.ToUnit(unit);
972
972
}}
973
973
else
974
974
{{
975
+
// No possible conversion
975
976
throw new NotImplementedException($""Can not convert {{Unit}} to {{unit}}."");
976
977
}}
977
978
}}
978
979
980
+
/// <summary>
981
+
/// Attempts to convert this <see cref=""{_quantity.Name}""/> to another <see cref=""{_quantity.Name}""/> with the unit representation <paramref name=""unit"" />.
982
+
/// </summary>
983
+
/// <param name=""unit"">The unit to convert to.</param>
984
+
/// <param name=""converted"">The converted <see cref=""{_quantity.Name}""/> in <paramref name=""unit""/>, if successful.</param>
985
+
/// <returns>True if successful, otherwise false.</returns>
986
+
private bool TryToUnit({_quantity.Name}Unit unit, out {_quantity.Name}? converted)
987
+
{{
988
+
if (_unit == unit)
989
+
{{
990
+
converted = this;
991
+
return true;
992
+
}}
993
+
994
+
converted = (_unit, unit) switch
995
+
{{
996
+
// {_quantity.Name}Unit -> BaseUnit");
997
+
998
+
foreach(varunitin_quantity.Units)
999
+
{
1000
+
if(unit.SingularName==_quantity.BaseUnit)
1001
+
continue;
1002
+
1003
+
var func = unit.FromUnitToBaseFunc.Replace("{x}","_value");
1004
+
Writer.WL($@"
1005
+
({_quantity.Name}Unit.{unit.SingularName}, {_unitEnumName}.{_quantity.BaseUnit}) => new {_quantity.Name}({func}, {_unitEnumName}.{_quantity.BaseUnit}),");
1006
+
}
1007
+
1008
+
Writer.WL();
1009
+
Writer.WL($@"
1010
+
1011
+
// BaseUnit -> {_quantity.Name}Unit");
1012
+
foreach(varunitin_quantity.Units)
1013
+
{
1014
+
if(unit.SingularName==_quantity.BaseUnit)
1015
+
continue;
1016
+
1017
+
var func = unit.FromBaseToUnitFunc.Replace("{x}","_value");
1018
+
Writer.WL($@"
1019
+
({_unitEnumName}.{_quantity.BaseUnit}, {_quantity.Name}Unit.{unit.SingularName}) => new {_quantity.Name}({func}, {_quantity.Name}Unit.{unit.SingularName}),");
0 commit comments