我目前有以下方法,它返回百分比值。例如,对于350,000美元的项目价格和7%的百分比,它返回24,500。
public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
{
decimal result = 0m;
if (percentage != null)
{
try
{
result = Convert.ToDecimal(baseValue * percentage / 100m);
}
catch (OverflowException)
{
result = 0;
Logger.Warn("OverflowException caught in GetPercentValue() - should better be handled UI-Sided!");
}
}
return result;
}
我不认为这是以正确的方式处理的,所以有没有办法在这种情况下避免异常?
当用户输入像999,999,999,999,999,999
这样的疯狂号码并计算9999999999%
时,会抛出OverflowException。这样我就无法检查percentage
或baseValue
<= decimal.MaxValue
只是因为它们不是......计算结果本身就超过了小数范围。
答案 0 :(得分:1)
这是一个老问题,但我遇到了类似的问题,并考虑提供一种可能的替代解决方案。当两个数字的某些计算产生的数字大于MaxValue时,就会出现问题。这会导致异常,很难以通常的方式进行测试:
decimal existingValue = decimal.MaxValue;
decimal newValue = (decimal)100;
//doesn't work -- exception thrown here
if(existingValue + newValue <= decimal.MaxValue)
{
}
似乎对我有用的解决方案(不使用Try-Catch块)是重写方程式,在本例中是减法:
if(decimal.MaxValue - existingValue >= newValue)
{
//DoSomething
}
由于减法,不会超出MaxValue。我还没有尝试过乘法/除法的例子,但我猜它也会起作用。
答案 1 :(得分:0)
错误处理应该(很可能)在方法之外完成。现在你正在隐藏异常并返回错误的结果(发生错误时返回0)。您的方法的调用者无法判断结果是否正确或是否是由于OverflowException。
我会改写这样的方法:
public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
{
if (percentage == null)
return 0;
return baseValue*(percentage.Value/100);
}
并且可选地添加一个验证方法,用户可以调用该方法在调用实际方法之前检查参数。验证错误可以在UI中显示:
public static string ValidatePercentValue(decimal? percentage, decimal baseValue)
{
try
{
GetPercentValue(percentage, baseValue);
return null;
}
catch (Exception ex)
{
return ex.Message;
}
}
除此之外......
baseValue*(percentage.Value/100)
......比......更好。
baseValue*percentage.Value/100
尝试计算decimal.MaxValue的100%。第一个工作,而第二个抛出OverflowException。