question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Int32.TryParse and F#+ tryParse give different results

See original GitHub issue

Description

Basically (tested with culture on en-US).

> let value: int option = tryParse "123,45";;
val value: int option = Some 12345

> Int32.TryParse "123,45";;
val it: bool * int = (false, 0)

In other words, integers cannot have thousand-separators with Int32.TryParse, but can with tryParse.

Conversely, it doesn’t allow decimals, which is good:

> let value: int option = tryParse "123.45";;
val value: int option = None

> Int32.TryParse "123.45";;
val it: bool * int = (false, 0)

Likewise there’s a similar difference with e-notation:

> let value: int option = tryParse "12345e4";;
val value: int option = Some 123450000

> Int32.TryParse "12345e4";;
val it: bool * int = (false, 0)

Repro steps

See above.

Expected behavior

From the description of the method, you’d expect the same behavior as the .NET functions, but they allow certain illegal values, or at least ambiguous, considering how .NET parses numbers.

Actual behavior

See above. This is caused by NumberStyles.Any, which is not used by Int32.TryParse or Decimal.TryParse. These use NumberStyles.Integer and NumberStyles.Decimal respectively (see source of .NET), which limit the allowed range.

Known workarounds

Create your own types or call Int32.TryParse directly, or create your own helper function.

Related information

Most recent F#+ and tested with .NET 6, but assuming it is the same on .NET 7.

Issue Analytics

  • State:open
  • Created 6 months ago
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
abelbraaksmacommented, Mar 27, 2023

Related: regardless of whether we’d fix this issue or not, perhaps we can update the documentation to specify that parse and tryParse uses InvariantCulture. Currently, it not being mentioned, may lead people to believe it works the same as XXX.Parse/TryParse from the BCL, that is, that it changes behavior depending on the current culture.

1reaction
abelbraaksmacommented, Jul 3, 2023

I would set the defaults to what I wrote before:

we should stay as close as possible to what .NET itself implements, to stick with the “principle of least suprised”.

not sure if parseStrict is the ideal choice, but I can’t think of anything better right now.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Int32.TryParse Method (System)
Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the conversion succeeded.
Read more >
c# - How the int.TryParse actually works
I have to know, about a string , whether it's a numeric value, but I don't want to convert it at the this...
Read more >
int.Parse() vs int.TryParse() - All You Need To Know
TryParse () method provides a more reliable option because it doesn't throw an exception if the string value you're trying to convert is...
Read more >
Advanced parsing using Int.TryParse in C# | Code4IT
We all use the simple int.TryParse method, but when parsing the input string requires more complex calculations, we can rely on those overloads....
Read more >
TryParse vs if TryParse : r/csharp
TryParse returns a boolean of whether it successfully parsed it or not. They are only the same if you are typing in valid...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found