我有以下内容:
string outOfRange = "2147483648"; // +1 over int.MaxValue
显然,如果输入的不是数字,这将失败:
var defaultValue = 0;
int.TryParse(outOfRange, out defaultValue);
我的问题是,既然这是一个数字,并且在使用int.TryParse()
时将失败,那么你如何判断它失败是因为字符串超出了存储容器的范围?
我有以下内容:
string outOfRange = "2147483648"; // +1 over int.MaxValue
var defaultValue = 0;
int.TryParse(outOfRange, out defaultValue);
我的问题是,既然这是一个数字,并且在使用int.TryParse()
时将失败,那么你如何判断它失败是因为字符串超出了存储容器的范围?
string outOfRange = "2147483648";
try
{
int.Parse(outOfRange);
}
catch (OverflowException oex)
{
}
catch (Exception ex)
{ }
Try/Catch
效率的小文章。可以解析为十进制数,然后检查范围,避免使用 try/catch
string s = "2147483648";
decimal.Parse(s) > int.MaxValue;
string outOfRange = "2147483648"; // +1 over int.MaxValue
int value;
if(! int.TryParse(outOfRange, out value)) {
try {
int.Parse(defaultValue);
} catch(OverflowException e) {
// was overflow
} catch(Exception e) {
// was other reason
}
}
TryParse
方法来处理而不涉及异常。
对于其他数字数据类型(如浮点数),也可以采用类似的方法。
Int64.TryParse
代替;如果它通过了,那么你就知道它超出了范围。如果失败了,那么你就知道输入有误。 - Chris Sinclair我会尝试解析,如果失败了,那么尝试解析更高容量的值。如果更高容量的值可以成功解析,那么你就知道它超出范围了。如果它同样无法解析,那么输入就是错误的。
string outOfRange = "2147483648"; // +1 over int.MaxValue
int result;
if (!Int32.TryParse(outOfRange, out result))
{
long rangeChecker;
if (Int64.TryParse(outOfRange, out rangeChecker))
//out of range
else
//bad format
}
很遗憾,我认为没有一种通用的方法可以适用于任何类型;您必须为所有类型编写实现。例如,对于 Int64
,该怎么办?也许可以使用 BigInteger
替代:
string outOfRange = "9223372036854775808"; // +1 over Int64.MaxValue
long result;
if (!Int64.TryParse(outOfRange, out result))
{
BigInteger rangeChecker;
if (BigInteger.TryParse(outOfRange, out rangeChecker))
//out of range
else
//bad format
}
编辑:由于我所知道的没有“BigDecimal”,因此使用double
浮点值可能更有趣,您可能还需要考虑极端情况下接近0的值(不确定)。可能您可以对BigInteger
检查进行变化,但您还必须考虑小数点(在这里可能最好使用简单的正则表达式只有数字、可选负号和最多一个小数点)。如果有任何小数点,您必须将它们截断并仅检查字符串的整数部分。
编辑x2:这里是一个相当丑陋的实现,用于检查double
值:
// +bajillion over Double.MaxValue
string outOfRange = "90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.1";
double result;
if (!Double.TryParse(outOfRange, out result))
{
string bigIntegerInput = outOfRange;
if (!Regex.IsMatch(bigIntegerInput, @"^-?[0-9]\d*(\.\d+)?$"))
//bad format
int decimalIndex = bigIntegerInput.IndexOf('.');
if (decimalIndex > -1)
bigIntegerInput = bigIntegerInput.Substring(0, decimalIndex);
BigInteger rangeChecker;
if (BigInteger.TryParse(bigIntegerInput, out rangeChecker))
//out of range
else
//bad format
}
BigInteger
进行解析。BigInteger bigInt;
bool isAnOutOfRangeInt = BigInteger.TryParse(input, out bigInt)
&& (bigInt > int.MaxValue || bigInt < int.MinValue);
// if you care to have the value as an int:
if (!isAnOutOfRangeInt)
{
int intValue = (int)bigInt;
}
我建议使用 System.Convert.ToInt32(String) 进行数据类型转换;因为它已经为你实现了 OverflowException 异常处理,非常方便。
这种方法十分简单,比如:
try
{
result = Convert.ToInt32(value);
Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.",
value.GetType().Name, value, result.GetType().Name, result);
}
catch (OverflowException)
{
Console.WriteLine("{0} is outside the range of the Int32 type.", value);
}
catch (FormatException)
{
Console.WriteLine("The {0} value '{1}' is not in a recognizable format.",
value.GetType().Name, value);
}
Parse
而不是TryParse
。然后在try/catch中使用它,因为它会给出适当的异常。请参阅http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx以了解详细信息。你需要寻找的异常是OverflowException。TryParse
返回一个 bool
,这与从 Parse
中获取许多不同的异常是不可比较的。 - meilke直接的方法是使用 Int32.Parse(string s) 并捕获 OverflowException
;
OverflowException
s 表示一个小于 MinValue 或大于 MaxValue 的数字。
IFormatProvider
,情况就更加复杂了。 - Joachim Isaksson
long
或者uint
,如果你知道只有正数),然后再检查是否符合Int32.Max/MinValue
是可行的吗? - Chris SinclairTry-Catch
并检查异常消息来获取一个想法,而不是使用int.TryParse
。 - YoavParse
方法来允许异常发生,也许?这只是我的好奇心和观察。 - Grant Thomasint
在+- 20亿时会溢出呢?使用情况应该决定您期望的实际输入范围,并根据该范围编写验证,您还应选择适当的数据类型。 - Matthew