TryParse 因负数而失败

发布于 2024-10-16 16:42:40 字数 1350 浏览 7 评论 0原文

我在让 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;
        }

变量“成功”对于 -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 感觉很好,因为这一切都在我们的系统内。有人看到我可能做错了什么吗?

I'm having a problem getting TryParse to work correctly for me. I have a list of values that I am almost assured are valid (as they come from another component in our system) but I would like to make sure there is proper error handling in place.

Here is an example list of my values:

20.00
20.00
-150.00

And here is the method I originally wrote:

 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;
        }

The variable 'successful' was returning false for -150.00, so I added 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;
        }

However, now that I have the NumberStyles in there, none of the numbers will parse! I feel good about having IFormatProvider set to null as this is all within our system. Does anyone see what I may be doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

如果没有你 2024-10-23 16:42:40

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

TryParse 返回一个布尔值(true/false),因此上面的代码应该是:

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;
        }

This is not how you are supposed to use TryParse.

TryParse returns a boolean (true/false), so your code above should be:

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;
        }

or more succinctly,

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;
        }
埋葬我深情 2024-10-23 16:42:40

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

上面使用的“成功”不是成功值,而是正在解析的实际数字。因此,如果您解析“-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.
}

Others are explaining how to do it right, but not really explaining what you're doing wrong.

Where you're using "successful" above isn't the success value, it's the actual number that is being parsed. So if you're parsing "-150.00" of course successful will be negative. The out value of TryParse is the actual parsed value and the boolean indicating whether the process was successful or not is the returned value. Using what you have to help understand would be something like:

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

In this case, isSuccessful will be TRUE, numericValue will be -150. When you're using user-provided values instead of the hardcoded one I used above you'll want to check:

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.
}
南烟 2024-10-23 16:42:40

其他答案对于使用 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 中提取十进制值的内联函数。

The other answers have got the right idea with regard to the proper way to use Decimal.TryParse. However, if I were writing the method in question, I'd use LINQ to work with LINQ-to-XML objects:

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

This version works the exact same way, but it uses the Enumerable.Sum method to calculate the total. All I have to supply is an inline function that extracts decimal values from an XElement.

海的爱人是光 2024-10-23 16:42:40

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

使用

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

bool successful = decimal.TryParse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value);

Came in from Google. Answer for me was the incoming culture was wrong - specifically in an incoming JSON file.

Use

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

or

bool successful = decimal.TryParse(xElement.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value);
記柔刀 2024-10-23 16:42:40

对于正在解析的负值,您的成功将是负数。你的 if (successful > 0) 才是让你绊倒的原因。

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

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

否则,请稍微更改您的逻辑,使其更像:

decimal val;
if (Decimal.TryParse(xElement.Value, out val)){
  // valid number
}

your successful is going to be negative for a negative value being parsed. your if (successful > 0) is what's tripping you up.

If they are almost positively going to be valid values, try using Convert.ToDecimal:

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

Otherwise, change your logic a bit to be more like:

decimal val;
if (Decimal.TryParse(xElement.Value, out val)){
  // valid number
}
∞梦里开花 2024-10-23 16:42:40

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

XElement.Element("nodename").Value

而不是 XElement.Value。至少我会这么做:)

I would suggest you to tell XElement which node value it should look for as in:

XElement.Element("nodename").Value

Instead of XElement.Value. at least that is what I would do :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文