views:

101

answers:

1

I am creating a type converter for use in a in-house library that should be able to convert from any type returned by a database (long, DBNull, bool, string, etc...) to any compatible type.

This all works fin and dandy for items that can either be casted:

try { return (T)value } catch(InvalidCaseException) { }

Or can be parsed:

see http://stackoverflow.com/questions/894640/convert-to-a-nullablet-from-a-string-using-reflection

However, I'm hitting a brick wall when I want this desired behavior:

Assert.That(
    2,
Is.EqualTo(
    Converter<long>.Convert("2.1")
));

The issue is that the Pasre and TryParse functions kick this back as an invalid format, when the real desired result is to truncate the decimal.

What do you think would be the best way to parse a string like "2.1" to an unknown value type using reflection?

EDIT: Currently I'm using:

if (Nullable.GetUnderlyingType(t) != null)
{
    t = Nullable.GetUnderlyingType(t);
}

MethodInfo parse = t.GetMethod("Parse", new Type[] { typeof(string) });

if (parse != null)
{
    object parsed = parse.Invoke(null, new object[] { value.ToString() });
    return (T)parsed;
}
else
{
    throw new InvalidOperationException("The value you specified is not a valid " + typeof(T).ToString());
}
+4  A: 

What version of .NET, and what range of values? One option, for example, would be to parse it as a decimal and convert it from there...

T val = Convert.ChangeType(decimal.Parse("2.1"), typeof(T))

(the above just shows the central conversion - it doesn't attempt to fit it into your existing code)

This won't work for huge/very small values, but probably won't suffer the same rounding issues as double.

Marc Gravell
I think that will work for me. Basically, if I want a double, the "Parse" will pick it up. However, if I have a number like "1000000000000.1" I wan that to be usable as a long. I see that a decimal is 128-bit, but does it have a greater fully-precise range than a long?
John Gietzen
In terms of the main value, it is only 96 bit - so yes, longer than long (64 bit); but it is slower as a consequence - no CPU support.
Marc Gravell