patterncsharpMinor
Enums for measurement units, with possible circular dependency
Viewed 0 times
unitswithmeasurementdependencypossiblecircularforenums
Problem
I have some enums that define measurement information, such as volume, mass, distance etc...
They are defined as such:
I have the need to display a short and long description for the units. A short description of meters in my case would be
What I'd done until now was use the
That has worked for something that had a type of
I defined a custom attribute to make it easier to display these properties when outputting them to file/screen etc... that looks like this:
```
///
/// Provides an interface for the display of Unit-type objects
///
public class UnitDisplayAttribute
: Attribute
{
///
/// The short display of the unit. Example: [N]
///
public string ShortDisplay { get; private set; }
///
/// Long long display of the unit. Example: Newtons
///
public string LongDisplay { get; private set; }
///
/// Construct the unit display attribute providing a short and long desc
They are defined as such:
///
/// Units for measurement of area.
///
public enum Area
{
///
/// Meters squared.
///
M2 = 0,
///
/// Feet squared.
///
FT2
}I have the need to display a short and long description for the units. A short description of meters in my case would be
[m] and the long would simply be Meters. There are other larger enums for things like acceleration that define Kilometers per hour per second/[km/h/s].What I'd done until now was use the
DescriptionAttribute attribute to provide simply the short description:///
/// Distance measurement units
///
public enum Distance
{
///
/// Meters.
///
[Description("[m]")]
M = 0,
...
}That has worked for something that had a type of
Distance. I've now got things that are defined as integer types that are actually a distance measurement:public class MovementSnapshot
{
///
/// The total distance traveled, in meters.
///
public int TotalTravelDistance { get; private set; }
///
/// The current speed of the car. In KM/H
///
public int Speed { get; private set; }
///
/// The maximum speed achieved. In KM/H
///
public int MaxSpeed { get; private set; }
}I defined a custom attribute to make it easier to display these properties when outputting them to file/screen etc... that looks like this:
```
///
/// Provides an interface for the display of Unit-type objects
///
public class UnitDisplayAttribute
: Attribute
{
///
/// The short display of the unit. Example: [N]
///
public string ShortDisplay { get; private set; }
///
/// Long long display of the unit. Example: Newtons
///
public string LongDisplay { get; private set; }
///
/// Construct the unit display attribute providing a short and long desc
Solution
I'm going to suggest a different approach entirely. I like OOP.
Create an interface.
And a Formatter Enum
And then implement the interface, over riding and overloading the
And now you can give your class' properties a "stronger" type.
Simply calling the
I didn't do it here, but at this point, you might want to start thinking about implementing unit converter methods as well as implementing the
Create an interface.
public interface IUnitOfMeasure
{
int Value { get; set; }
string ShortDescription { get; }
string LongDescription { get; }
}And a Formatter Enum
public enum UnitOfMeasureFormat { Short, Long }And then implement the interface, over riding and overloading the
ToString() method. public class Meters : IUnitOfMeasure
{
public int Value { get; set; }
public string ShortDescription { get { return "[m]"; }
public string LongDescription { get { return "Meters"; }
public override string ToString()
{
return this.Value + " " + this.ShortDescription;
}
public string ToString(UnitOfMeasureFormat format)
{
if (format == UnitOfMeasureFormat.Short)
{
return this.ToString();
}
return this.Value + " " + this.LongDescription;
}
}And now you can give your class' properties a "stronger" type.
public class MovementSnapshot
{
public Meters TotalTravelDistance { get; private set; }Simply calling the
ToString() method when you need to display it. myMovementSnapshot.TotalTravelDistance.ToString();I didn't do it here, but at this point, you might want to start thinking about implementing unit converter methods as well as implementing the
IEquatable and IComparable interfaces.Code Snippets
public interface IUnitOfMeasure
{
int Value { get; set; }
string ShortDescription { get; }
string LongDescription { get; }
}public enum UnitOfMeasureFormat { Short, Long }public class Meters : IUnitOfMeasure
{
public int Value { get; set; }
public string ShortDescription { get { return "[m]"; }
public string LongDescription { get { return "Meters"; }
public override string ToString()
{
return this.Value + " " + this.ShortDescription;
}
public string ToString(UnitOfMeasureFormat format)
{
if (format == UnitOfMeasureFormat.Short)
{
return this.ToString();
}
return this.Value + " " + this.LongDescription;
}
}public class MovementSnapshot
{
public Meters TotalTravelDistance { get; private set; }myMovementSnapshot.TotalTravelDistance.ToString();Context
StackExchange Code Review Q#82686, answer score: 4
Revisions (0)
No revisions yet.