Skip to content

UnitAbbreviationsCache.GetDefaultAbbreviation(Type unitType) fails on boxed enums #1062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Extragorey opened this issue Mar 14, 2022 · 2 comments
Labels

Comments

@Extragorey
Copy link

Describe the bug
Calling UnitAbbreviationsCache.Default.GetDefaultAbbreviation(unitType) throws a NotImplementedException (e.g. "No abbreviation is specified for Enum.Millimeter") when passed a value of System.Enum {UnitsNet.Units.LengthUnit} instead of UnitsNet.Units.LengthUnit. Its sister methods GetUnitAbbreviations<TUnitType>() and GetUnitAbbreviations() behave the same way.

To Reproduce
Steps to reproduce the behavior (just an example):

  1. Add nuget UnitsNet 4.125.0 to a .NET 6.0 project
  2. Build using Visual Studio 2022 Community v17.0.1
  3. Attempt to execute the following code:
string quantityName = "Length";
string unitName = "Millimeter";
var quantityInfo = Quantity.ByName.FirstOrDefault(d => d.Key == quantityName).Value;
if (quantityInfo != default && Enum.TryParse(quantityInfo.UnitType, unitName, out var unitInfo)) {
    // This line throws a NotImplementedException
    string abbreviation = UnitAbbreviationsCache.Default.GetDefaultAbbreviation((Enum)unitInfo);
}

Expected behavior
The method should return the abbreviated form of millimeter ("mm").

Additional notes
The rationale behind this use case is to find the abbreviation of a unit that is only known at runtime, i.e. from the strings "Length" and "Millimeter".
An alternative workaround would be possible if an Abbreviation property was added to the UnitInfo class alongside the full Name property, or alternatively if a GetAbbreviation(Enum unitEnum) method was added to the QuantityInfo class.

@Extragorey Extragorey added the bug label Mar 14, 2022
@angularsen
Copy link
Owner

Thanks for reporting and providing a good repro.

It is not super intuitive, but I believe you can achieve what you want by:

string abbreviation = UnitAbbreviationsCache.Default.GetDefaultAbbreviation(unitInfo.GetType(), (int)unitInfo);

On a side-note, we are generally trying to move away from enums and towards string based values, to better support third-party conversions and units.
QuantityType enum is deprecated and will be removed in v5 in favor of passing strings like Length.
I assume we could do something similar for the quantity unit enums like LengthUnit, and maybe provide overloads like this:

string abbreviation = UnitAbbreviationsCache.Default.GetDefaultAbbreviation("Length", "Millimeter");

It requires some refactoring, but should be possible without a breaking change.
cc @tmilnthorp

@Extragorey
Copy link
Author

Thanks, I was able get the abbreviation by calling:

UnitAbbreviationsCache.Default.GetDefaultAbbreviation(unitInfo.GetType(), Convert.ToInt32(unitInfo))

The proposed move to string inputs also sounds like a useful change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants