9

我在让 TryParse 为我正常工作时遇到问题。我有一个我几乎可以肯定是有效的值列表(因为它们来自我们系统中的另一个组件),但我想确保有适当的错误处理。

这是我的价值观的示例列表:

20.00
20.00
-150.00

这是我最初写的方法:

 private decimal CalculateValue(IEnumerable<XElement> summaryValues)
        {
            decimal totalValue = 0;

            foreach (XElement xElement in summaryValues)
            {
                decimal successful;
                Decimal.TryParse(xElement.Value, out successful);
                if (successful > 0)
                    totalValue += Decimal.Parse(xElement.Value);
            }
            return totalValue;
        }

变量 'successful' 为 -150.00 返回 false,所以我添加了 NumberStyles:

private decimal CalculateValue(IEnumerable<XElement> summaryValues)
        {
            decimal totalValue = 0;

            foreach (XElement xElement in summaryValues)
            {
                decimal successful;
                Decimal.TryParse(xElement.Value, NumberStyles.AllowLeadingSign, null, out successful);
                if (successful > 0)
                    totalValue += Decimal.Parse(xElement.Value, NumberStyles.AllowLeadingSign);
            }
            return totalValue;
        }

但是,现在我有 NumberStyles 了,没有一个数字会解析!我对将 IFormatProvider 设置为 null 感觉很好,因为这一切都在我们的系统中。有谁看到我可能做错了什么?

4

6 回答 6

11

这不是您应该使用 TryParse 的方式。

TryParse 返回一个布尔值(真/假),所以你上面的代码应该是:

private decimal CalculateValue(IEnumerable<XElement> summaryValues)
        {
            decimal totalValue = 0;

            foreach (XElement xElement in summaryValues)
            {
                decimal valueReturned;
                bool successful = Decimal.TryParse(xElement.Value, out valueReturned);
                if (successful)
                    totalValue += valueReturned;
            }
            return totalValue;
        }

或更简洁地说,

private decimal CalculateValue(IEnumerable<XElement> summaryValues)
        {
            decimal totalValue = 0;

            foreach (XElement xElement in summaryValues)
            {
                decimal valueReturned;
                if (Decimal.TryParse(xElement.Value, out valueReturned))
                    totalValue += valueReturned;
            }
            return totalValue;
        }
于 2011-02-07T18:58:19.773 回答
4

其他人正在解释如何正确地做这件事,但并没有真正解释你做错了什么。

您在上面使用“成功”的地方不是成功值,而是正在解析的实际数字。所以如果你解析“-150.00”当然成功将是负面的。TryParse 的 out 值是实际解析的值,指示处理是否成功的布尔值是返回值。使用您必须帮助理解的内容将类似于:

string inputValue = "-150.00";
decimal numericValue;
bool isSucessful = Decimal.TryParse(inputValue , out numericValue);

在这种情况下,isSuccessful 将为 TRUE,numericValue 将为 -150。当您使用用户提供的值而不是我上面使用的硬编码值时,您需要检查:

if(isSuccessful)
{
    // Do something with numericValue since we know it to be a valid decimal
}
else
{
    // Inform User, throw exception, etc... as appropriate, Don't use numericValue because we know it's wrong.
}
于 2011-02-07T19:32:44.957 回答
3

其他答案对正确使用方法有正确的想法Decimal.TryParse。但是,如果我正在编写有问题的方法,我会使用 LINQ 来处理 LINQ-to-XML 对象:

private decimal CalculateValue(IEnumerable<XElement> summaryValues)
{
    return summaryValues
        .Sum(el =>
             {
                 decimal value;
                 if (Decimal.TryParse(el.Value, out value))
                     return value;
                 return 0M;
             });
}

这个版本的工作方式完全相同,但它使用Enumerable.Sum方法来计算总数。我只需要提供一个从 XElement 中提取十进制值的内联函数。

于 2011-02-07T19:58:39.317 回答
2

从谷歌进来。对我来说,答案是传入的文化是错误的——特别是在传入的 JSON 文件中。

采用

totalValue += decimal.Parse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture);

或者

bool successful = decimal.TryParse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
于 2016-06-03T20:04:25.410 回答
1

对于被解析的负值,您的成功将是负数。你if (successful > 0)是什​​么让你绊倒。

如果它们几乎肯定是有效值,请尝试使用Convert.ToDecimal

decimal val = Convert.ToDecimal(xElement.Value);

否则,将您的逻辑更改为更像:

decimal val;
if (Decimal.TryParse(xElement.Value, out val)){
  // valid number
}
于 2011-02-07T18:58:30.570 回答
0

我建议您告诉 XElement 它应该查找哪个节点值,如下所示:

XElement.Element("nodename").Value

而不是 XElement.Value。至少那是我会做的:)

于 2011-02-07T18:58:51.727 回答