现象
数字字符串,格式形式为 x.0 时
var rest1 = int.Parse(numStr);
var rest2 = Convert.ToInt32(numStr);
直接使用如上转换会发生运行时异常。
数字字符串,格式形式为 x.f (f >0)时
如图,转换全部异常。
解决
不论是使用 int.Parse 还是 Convert.ToInt32,最终都是使用 int.Parse 的实现。为了弱化数字字符串格式的的不确定,建议先用 decimal.Parse 转成decimal类型的数字,在对其做具体的业务处理。
安全的转 int 方法
/// <summary>
/// 转Int扩展方法
/// </summary>
/// <param name="obj"></param>
/// <param name="defaultValue"></param>
/// <param name="isRounding"></param>
/// <param name="midpointRounding"></param>
/// <returns></returns>
public static int AsInt(this object obj,int defaultValue = 0,bool isRounding = false,MidpointRounding midpointRounding = MidpointRounding.AwayFromZero)
{
if(obj == null || obj == DBNull.Value)
{
return defaultValue;
}
try
{
decimal value;
var tryResult = decimal.TryParse(obj.ToString(), out value);
if(!tryResult || value> int.MaxValue || value < int.MinValue)
{
return defaultValue;
}
if (isRounding)
{
return (int)Math.Round(value, midpointRounding);
}
return (int)value;
}
catch
{
return defaultValue;
}
}
实现底层
int.Parse()
此转换,对数字字符串的格式有约定,具体约定为NumberStyles 枚举下的值定义。它不能处理 x.f (f>0)的小数数字字符串的转换。
1. 相关API:
2. Number.ParseInt32()方法
3. NumberStyles 枚举
用法:
int.Parse("1.0", NumberStyles.Float); //单个使用
int.Parse("1.0", NumberStyles.Number | NumberStyles.Float | NumberStyles.Currency); //复合使用
作用:
a. 单个字段标志,用于定义特定样式元素 (,例如空格和组分隔符) ,这些元素可以存在于分析的字符串中。
b. 复合数字样式,由多个字段标志组成,这些标志定义可在分析字符串中存在的样式元素。
4.NumberFormatInfo 类
Convert.ToInt32()
1. 相关API
底层实质还是调用的 int.Parse的相关方方法,且指定了NumberStyles 和 IFormatProvider 两个参数。
2. CultureInfo 类
官方释义
作用:提供有关特定区域性(对于非托管代码开发,则称为“区域设置”)的信息。 这些信息包括区域性的名称、书写系统、使用的日历、字符串的排序顺序以及对日期和数字的格式化设置。