使用TypeConverter.ConvertFrom使用数千个分隔符解析数值类型

psu*_*003 1 c# generics parsing

我有一个现有的泛型方法,用于解析XML文件中的各种数字类型

public static Nullable<T> ToNullable<T>(this XElement element) where T : struct
{
    Nullable<T> result = new Nullable<T>();

    if (element != null)
    {
        if (element.HasElements) throw new ArgumentException(String.Format("Cannot convert complex element to Nullable<{0}>", typeof(T).Name));

        String s = element.Value;
        try
        {
            if (!string.IsNullOrWhiteSpace(s))
            {
                TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
                result = (T)conv.ConvertFrom(s);
            }
        }
        catch { }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,输入XML文件开始包含包含数千个分隔符的数字字符串(例如:353,341.37).逗号的存在现在导致上述方法在转换中失败,但是,我想像任何其他数字类型一样解析它

我所知道的各种ParseTryParse方法包含接受过载NumberStyles枚举,将修正解析这些值,但由于我使用的是通用的方法,这些方法都无法使用,直到我要创建几个类型的具体方法.

有没有办法在泛型方法中使用千位分隔符解析数值类型?

bra*_*chd 5

您也可以替换默认的DoubleConverter.

首先,创建一个将成为转换器的类:

    class DoubleConverterEx : DoubleConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                string text = ((string)value).Trim();
                // Use the InvariantCulture, which accepts ',' for separator
                culture = CultureInfo.InvariantCulture;

                NumberFormatInfo formatInfo = (NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo));
                return Double.Parse(text, NumberStyles.Number, formatInfo);
            }
            return base.ConvertFrom(value);
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后将此类注册为double的转换器:

TypeDescriptor.AddAttributes(typeof(double), new TypeConverterAttribute(typeof(DoubleConverterEx)));
Run Code Online (Sandbox Code Playgroud)

现在你的转换器将被调用,因为它都使用带有','分隔符的文化,并且传递允许你的格式的NumberStyles值,它将解析.

测试程序:

    static void Main(string[] args)
    {
        TypeDescriptor.AddAttributes(typeof(double), new TypeConverterAttribute(typeof(DoubleConverterEx)));
        TypeConverter converter = TypeDescriptor.GetConverter(typeof(double));
        string number = "334,475.79";
        double num = (double)converter.ConvertFrom(number);
        Console.WriteLine(num);
    }
Run Code Online (Sandbox Code Playgroud)

打印:

334475.79
Run Code Online (Sandbox Code Playgroud)

对于导致问题的类型(小数,浮点数),您可以执行类似的操作.

免责声明:转换器本身的实现非常基础,可能需要抛光.希望有所帮助.