I have some enums that define measurement information, such as volume, mass, distance etc...
They are defined as such:
/// <summary>
/// Units for measurement of area.
/// </summary>
public enum Area
{
/// <summary>
/// Meters squared.
/// </summary>
M2 = 0,
/// <summary>
/// Feet squared.
/// </summary>
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:
/// <summary>
/// Distance measurement units
/// </summary>
public enum Distance
{
/// <summary>
/// Meters.
///</summary>
[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
{
/// <summary>
/// The total distance traveled, in meters.
/// </summary>
public int TotalTravelDistance { get; private set; }
/// <summary>
/// The current speed of the car. In KM/H
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// The maximum speed achieved. In KM/H
/// </summary>
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:
/// <summary>
/// Provides an interface for the display of Unit-type objects
/// </summary>
public class UnitDisplayAttribute
: Attribute
{
/// <summary>
/// The short display of the unit. Example: [N]
/// </summary>
public string ShortDisplay { get; private set; }
/// <summary>
/// Long long display of the unit. Example: Newtons
/// </summary>
public string LongDisplay { get; private set; }
/// <summary>
/// Construct the unit display attribute providing a short and long description of a unit type.
/// </summary>
/// <param name="longDisplay"></param>
/// <param name="shortDisplay"></param>
public UnitDisplayAttribute(string longDisplay, string shortDisplay)
{
this.ShortDisplay = shortDisplay;
this.LongDisplay = longDisplay;
}
}
This would work well but I'm now running into this situation when applying the attribute to the class I defined above:
public class MovementSnapshot
{
/// <summary>
/// The total distance traveled, in meters.
/// </summary>
[UnitDisplay("[m]", "Meters")]
public int TotalTravelDistance { get; private set; }
/// <summary>
/// The current speed of the car. In KM/H
/// </summary>
[UnitDisplay("[km/h]", "Kilometers per hour")]
public int Speed { get; private set; }
/// <summary>
/// The maximum speed achieved. In KM/H
/// </summary>
[UnitDisplay("[km/h]", "Kilometers per hour")]
public int MaxSpeed { get; private set; }
}
I have to duplicate the attribute for properties measured in the same units... Some classes have 10-12 of them. I then thought of adding a constructor to the UnitDisplayAttribute
class that takes an instance of Distance
for example, and could provide a string method to output the display.
/// <summary>
/// Provides an interface for the display of Unit-type objects
/// </summary>
public class UnitDisplayAttribute
: Attribute
{
/// <summary>
/// The short display of the unit. Example: [N]
/// </summary>
public string ShortDisplay { get; private set; }
/// <summary>
/// Long long display of the unit. Example: Newtons
/// </summary>
public string LongDisplay { get; private set; }
public UnitDisplayAttribute(Distance d)
{
// check if the distance is meters, kilometers etc... and apply the appropriate short and long strings to the property.
}
}
That will work well for my MovementSnapshot
class above, but applying the custom attribute to the Distance
enum above feels awkward because the attribute takes an object of the same type:
/// <summary>
/// Distance measurement units
/// </summary>
public enum Distance
{
/// <summary>
/// Meters.
///</summary>
[UnitDisplay(Distance.M)]
M = 0,
...
}
Am I worrying about nothing here? Will Jimmy lose his mind while looking at this code? How can I achieve a nice display for objects that are represented as a unit and objects that are that unit?
MovementSnapshot
example, should we assume there's aSpeed
enum with a value for kilometers per hour? \$\endgroup\$