Int32.TryParse and F#+ tryParse give different results
See original GitHub issueDescription
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:
- Created 6 months ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
Related: regardless of whether we’d fix this issue or not, perhaps we can update the documentation to specify that
parse
andtryParse
usesInvariantCulture
. Currently, it not being mentioned, may lead people to believe it works the same asXXX.Parse/TryParse
from the BCL, that is, that it changes behavior depending on the current culture.I would set the defaults to what I wrote before:
not sure if
parseStrict
is the ideal choice, but I can’t think of anything better right now.