【问题标题】:Converting hexadecimal string to dynamic primitive type将十六进制字符串转换为动态原始类型
【发布时间】:2010-09-10 14:06:29
【问题描述】:

我有以下代码:

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

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

一旦执行就会引发 System.FormatException,因为显然 Convert.ChangeType 不能使用十六进制值。

我的其他替代方案正在使用以下任何一种:

  • Int32.Parse
  • 转换。ToInt32

但是,由于它们适用于特定类型,因此我需要使用 switch/reflection 来为正确的类型选择正确的函数。

我对这两种选择都不是很兴奋。还有什么我可以做的吗?

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    由于十六进制通常只用于整数,您可以将parse字符串转换为最大整数类型(Int64)和change将结果类型转换为所需类型:

    string hexString = "deadcafebabe0000";
    long hexValue = long.Parse(hexString, NumberStyles.AllowHexSpecifier);
    
    Type hexType = typeof(Int32);
    object o = Convert.ChangeType(hexValue, hexType);
    

    (请注意,在将字符串传递给 Parse 方法之前,您需要去掉 0x 前缀。)


    Convert.ChangeType 本质上是一大堆if (type == ...) ... else if (type == ...) 语句。您可以创建一个字典,将所有整数类型映射到它们各自的 Parse 方法:

    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);
    

    【讨论】:

    • @VitalyB:负十六进制数字是一个丑陋的极端情况,因为它们不是用- 符号(以 16 为基数)表示,而是用二进制补码表示。这意味着您需要使用与原始值完全相同的类型来解析字符串。
    • 我希望有更多内置的东西。哦,好吧,我想我会去的。谢谢!
    猜你喜欢
    • 2021-06-24
    • 2016-07-24
    • 2017-09-28
    • 1970-01-01
    • 2018-01-31
    • 2018-01-22
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    相关资源
    最近更新 更多