TheSean
TheSean

Reputation: 4566

How Can I Convert Between Two (numeric) Data Types Without Losing Any Data?

I need to convert between various types (decimal, int32, int64, etc.) but I want to make sure I am not loosing any data. I've found that normal Convert methods (including casting) will truncate data without warning.

decimal d = 1.5;
int i = (int)d;
// i == 1

I would like if there was a convert or TryConvert method that would throw or return false if a conversion was dropping data. How can I accomplish this?

If possible, I would like to do this in a generic sense, so I can do it all given two Type objects, and an object instance (where runtime type is convertFrom type). Like this:

object ConvertExact(object convertFromValue, Type convertToType)
{
    if ( ** conversion not possible, or lossy ** )
        throw new InvalidCastException();

    // return converted object
}

Similar to this question, but here the number is truncated.

Upvotes: 2

Views: 307

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499860

How about this:

using System;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(ConvertExact(2.0, typeof(int)));
        Console.WriteLine(ConvertExact(2.5, typeof(int)));
    }

    static object ConvertExact(object convertFromValue, Type convertToType)
    {
        object candidate = Convert.ChangeType(convertFromValue,
                                              convertToType);
        object reverse =  Convert.ChangeType(candidate,
                                             convertFromValue.GetType());

        if (!convertFromValue.Equals(reverse))
        {
            throw new InvalidCastException();
        }
        return candidate;
    }
}

Note that this isn't perfect - it will happily convert both 2.000m and 2.00m to 2 for example, despite the fact that that does lose information (the precision). It's not losing any magnitude though, and this may be good enough for you.

Upvotes: 6

Related Questions