I have a namespace of structs which represent various units of measure (Meters, Feet, Inches, etc.) ... anout 12 in total, generated courtesy of T4 templates :) .
Each struct carries implicit casting operators to support casting the value to any other measurement value-type, so the following sytax is legal:
var oneThousandMeters = new Meters(1000);
Kilometers aKilo = oneThousandMeters ; // implicit cast OK. Value = 1 Km
To add to the joy, there's a catch-all class called Distance which can hold any unit of measure, and can also be implicitly cast to and from and measurement value...
var magnum = new Distance(12, DistanceUnits.Inches);
Feet wifesDelight = magnum; // implicit cast OK. Value = 1 foot.
Following the .NET framework standard, all string formatting and parsing is handled by external a FormatProvider, which implements ICustomFormatter. Sadly, this means that the value is boxed when it is passed to the Format method, and the format method needs to test the object against every known measurement type before it can act upon it. Internally, the Format method just casts the measurement to a Distance value anyway, so here comes the question....
Question:
public string Format(string format, object arg, IFormatProvider formatProvider)
{
Distance distance;
// The following line is desired, but fails if arg != typeof(Distance)
distance = (Distance)arg;
// But the following tedious code works:
if(arg is Distance)
distance = (Distance)arg;
else if(arg is Meters)
distance = (Distance)(Meters)arg; // OK. compile uses implicit cast.
else if(arg is Feet)
distance = (Distance)(Feet)arg; // OK. compile uses implicit cast.
else if(arg is Inches)
distance = (Distance)(Inches)arg; // OK. compile uses implicit cast.
else
... // tear you hair out for all 12 measurement types
}
Are there any solutions for this, or is this just one of those unsolvable drawbacks of value types?
PS: I've checked this post, and though the question is similar, it's not what I'm looking for.