I\'m implementing value types which represents a distance (or length). There\'s an enum that represents the different units of measure, eg:
public enum Distance
Maybe all you need is a function that returns a corresponding unit subset
class UnitSystem
{
public enum Type
{
Metric,
Imperial
}
public static DistanceUnit[] GetUnits(Type type)
{
switch (type)
{
case Type.Metric:
return new DistanceUnit[] {
DistanceUnit.Millimeter,
DistanceUnit.Centimeter,
DistanceUnit.Meter,
DistanceUnit.Kilometer
}
case Type.Imperial:
return new DistanceUnit[] {
DistanceUnit.Inch,
DistanceUnit.Foot,
DistanceUnit.Yard,
DistanceUnit.Mile
}
}
}
public static Type GetType(DistanceUnit unit)
{
switch (unit)
{
case DistanceUnit.Millimeter:
case DistanceUnit.Centimeter:
case DistanceUnit.Meter:
case DistanceUnit.Kilometer:
return Type.Metric;
case DistanceUnit.Inch:
case DistanceUnit.Foot:
case DistanceUnit.Yard:
case DistanceUnit.Mile:
return Type.Imperial;
}
}
}
Generally speaking, I would go with Anton's solution. But if your implementation can't use that, and you need things to be used similar to an enum, I think this is a natural way to use the units:
DistanceUnit.Metric.Millimeter
DistanceUnit.Imperial.Inch
In order to use it like that, there should be:
public static class DistanceUnit
{
public static MetricDistanceUnit Metric;
public static ImperialDistanceUnit Imperial;
}
Where MetricDistanceUnit
is:
public enum MetricDistanceUnit
{
Millimeter, Centimeter ...
}
And ImperialDistanceUnit
has the same structure..
Do you really need an enum
here? Maybe, a simple value object will do?
public class Distance
{
private readonly decimal millimeters;
public decimal Meters
{
get { return millimeters * 0.001m; }
}
private Distance(decimal millimeters)
{
this.millimeters = millimeters;
}
public static Distance Yards(decimal yards)
{
return new Distance(yards * 914.4m);
}
}
With extension methods you and properly defined operators can get very Ruby-like syntax:
var theWholeNineYards = 9.Yards() + 34.Inches();