11

In my code I frequently use the following Converts:

Convert.ToInt32(value, Cultureinfo.InvariantCulture);
Convert.ToDecimal(value, CultureInfo.InvariantCulture);

I now do like to use TryParse functions because of recent errors. I'm not entirely sure if i'm correct in using the following equivalents as I do not completely understand the NumberStyles enum.

Int64.TryParse(value, NumberStyles.Any, CultureInfo.invariantCulture, out output);
Decimal.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out output);

EDIT BELOW after answers

The following code should then be the correct alternative:

Int64.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out output);
Decimal.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out output);
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
Schuere
  • 1,579
  • 19
  • 33

3 Answers3

8

You can read about NumberStyles in the documentation. Essentially it allows you to specify what sort of text will parse.

If you want to be as flexible as possible, then NumberStyles.Any is the 'widest' option.

Convert.ToInt32 is equivalent to using int.Parse and Convert.ToDecimal is equivalent to using decimal.Parse - they delegate to these methods.

Per the documentation for int.Parse, the default is NumberStyles.Integer. And per the documentation for decimal.Parse, the default is NumberStyles.Number. If you want to be consistent with the behaviour of Convert.ToInt32 and Convert.ToDecimal, you should use these values.

Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • Wouldn't `NumberStyles.Any | NumberStyles.AllowHexSpecifier` be the wider option than just `NumberStyles.Any`, or would that combination be illegal? – stakx - no longer contributing May 22 '15 at 10:40
  • I changed the question with your and dcastro's answer tyvm – Schuere May 22 '15 at 10:41
  • 2
    @stakx it seems it's illegal. The docs say *The only flags that can be combined with AllowHexSpecifier are AllowLeadingWhite and AllowTrailingWhite.*. I tried it and got an exception to that effect. – Charles Mager May 22 '15 at 10:42
5

The documentation for Int64.TryParse says NumberStyles.Integer is the default:

The s parameter is interpreted using the NumberStyles.Integer style. In addition to the decimal digits, only leading and trailing spaces together with a leading sign are allowed.

For Decimal.TryParse, it's NumberStyles.Number:

Parameter s is interpreted using the NumberStyles.Number style. This means that white space and thousands separators are allowed but currency symbols are not.

dcastro
  • 66,540
  • 21
  • 145
  • 155
  • 1
    This would explicitly not correspond with `decimal` which can have floating values. `NumberStyles.Float` would be more appropriate, given the two usecases in the question (or just generally `NumberStyles.Number)`. – Jeroen Vannevel May 22 '15 at 10:28
  • I changed the question with your and charles mager's answer tyvm – Schuere May 22 '15 at 10:41
4

Yes your approach is correct, both approaches should give the same results.

The implementation of Convert.ToInt32(string s) is as follows:

public static int ToInt32(String value, IFormatProvider provider)
{
    if (value == null)
        return 0;
    return Int32.Parse(value, NumberStyles.Integer, provider);
 }

So as you can see internally one method calls the other - the only difference is that with Convert you don't have control over the number style - it is hardcoded to NumberStyles.Integer. If you want identical functionality you should specify this enum value in your calls to TryParse.

Source code for the Convert class is available here.

May I also point out that you are calling Int64.TryParse when if Convert.ToInt32 was sufficient then so should be Int32.TryParse.

Jurgen Camilleri
  • 3,559
  • 20
  • 45
  • I didn't downvote, but I have two suggestions: **1.** Cite your sources! (How did you come by the implementation of `Convert.ToInt32`?) **2.** Your answer suggests that `NumberStyles.Integer` would be the one to go for; but you initially say that the OP's current code is equivalent (they use `NumberStyles.Any`). Perhaps you could go more into `NumberStyles.Any`. – stakx - no longer contributing May 22 '15 at 10:33
  • 1
    I reflected into `mscorlib` - no need to cite that :) – Jurgen Camilleri May 22 '15 at 10:34
  • 1
    Actually, you *should* say so. Reverse-engineering an assembly, apart from possible legal issues (but IANAL), results in knowledge that might be subject to change at any time. I'd say one should prefer the Reference Source (the name says it all) over decompilation when answering on SO. That's just my opinion, though. – stakx - no longer contributing May 22 '15 at 10:36
  • 1
    I added a link to MS Reference Source. – Jurgen Camilleri May 22 '15 at 10:37
  • 1
    I changed the question with dcastro's and charles mager's answer, your answer to was very helpful for me to understand more of the Convert.ToInt methods +1 – Schuere May 22 '15 at 10:42