Error TryParse with negative numbers

I had a problem with TryParse working correctly for me. I have a list of values โ€‹โ€‹that I'm pretty sure are valid (since they come from another component in our system), but I would like to make sure that there is proper error handling in place.

Here is an example of a 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 "success" returned 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 NumberStyles, none of the numbers will be parsed! Iโ€™m good that IFormatProvider is set to null, because thatโ€™s all on our system. Does anyone see what I can do wrong?

+7
source share
6 answers

Other answers have the right idea regarding the proper use of Decimal.TryParse . However, if I were to write this method, I would 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 same way, but uses the Enumerable.Sum method to calculate the total. All I have to provide is a built-in function that extracts decimal values โ€‹โ€‹from XElement.

+3
source

This is not how you should use TryParse.

TryParse returns a boolean value (true / false), so your code 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; } 
+11
source

Others explain how to do it right, but do not explain what you are doing wrong.

If you use the โ€œsuccessfulโ€ above, this is not the meaning of success, this is the actual number that is being analyzed. Therefore, if you parse "-150.00", of course, successful will be negative. The original TryParse value is the actual parsed value, and the boolean value indicates whether the process was successful or not - this is the return value. Using what you need to 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 use user-entered values โ€‹โ€‹and not hard-coded ones that I used above, you 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 wrong. } 
+4
source

your successful result will be negative when analyzing a negative value. your if (successful > 0) is what disconnects you.

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

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

Otherwise, change the logic a bit:

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

I suggest you tell XElement, the value of node, which should look like this:

 XElement.Element("nodename").Value 

Instead of XElement.Value. at least that's what i would do :)

0
source

Came from Google. The answer for me was that the incoming culture was wrong - especially in the 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); 
0
source

All Articles