tags:

views:

48

answers:

1

Hi everyone,

I have the following code:

        string hexString = "0x00000004";
        Type hexType = typeof(Int32);

        object o = Convert.ChangeType(hexString, hexType);

Which throws a System.FormatException as soon as it is executed as, apparantly, Convert.ChangeType can't work with hexadecimal values.

My other alternatives are using either of these:

  • Int32.Parse
  • Convert.ToInt32

However, since they apply for a specific type, I'll need to use a switch/reflection to choose the correct function for the correct type.

I am not really excited about either of these options. Is there anything else I can do?

+1  A: 

Since hexadecimal is usually used only for integer numbers, you can parse the string to the largest integer type (Int64) and change the type of the result to the desired type:

string hexString = "deadcafebabe0000";
long hexValue = long.Parse(hexString, NumberStyles.AllowHexSpecifier);

Type hexType = typeof(Int32);
object o = Convert.ChangeType(hexValue, hexType);

(Note that you need to strip out the 0x prefix before passing the string to the Parse method.)


Convert.ChangeType is essentially a big pile of if (type == ...) ... else if (type == ...) statements. You could create a dictionary that maps all integer types to their respective Parse method:

var dict = new Dictionary<Type, Func<string, object>>
{
    { typeof(byte),   s => byte.Parse(s, NumberStyles.AllowHexSpecifier) },
    { typeof(sbyte),  s => sbyte.Parse(s, NumberStyles.AllowHexSpecifier) },
    { typeof(short),  s => short.Parse(s, NumberStyles.AllowHexSpecifier) },
    { typeof(ushort), s => ushort.Parse(s, NumberStyles.AllowHexSpecifier) },
    { typeof(int),    s => int.Parse(s, NumberStyles.AllowHexSpecifier) },
    { typeof(uint),   s => uint.Parse(s, NumberStyles.AllowHexSpecifier) },
    { typeof(long),   s => long.Parse(s, NumberStyles.AllowHexSpecifier) },
    { typeof(ulong),  s => ulong.Parse(s, NumberStyles.AllowHexSpecifier) },
};

string hexString = (-5).ToString("X");
Type hexType = typeof(Int32);
object o = dict[hexType](hexString);
dtb
We've considered this options. Unfortunately, negative numbers give trouble in this case. Consider this code, using your example:`string hexString = string.Format("{0:X}", -5);``long hexValue = long.Parse(hexString, NumberStyles.AllowHexSpecifier);``Type hexType = typeof(Int32);``object o = Convert.ChangeType(hexValue, hexType);`Your solution, in this case throws System.OverflowException
VitalyB
@VitalyB: Negative hexadecimal numbers are an ugly corner case, because they're not represented with a `-` sign (base 16) but in its Two's complement. This means you need to parse the string using exactly the same type as the original value.
dtb
I was hoping for something more built-in. Oh well, I guess I'll go with this. Thanks!
VitalyB