19

I am a little confused here.

What should I use

Console.WriteLine((val/1085).ToString("N"));

VS

Console.WriteLine(String.Format("{0:N}", (val/1085)));

Also how do I fit the InvariantCulture? ANY BEST PRACTICES :)?

Matt
  • 25,467
  • 18
  • 120
  • 187
Joe
  • 515
  • 2
  • 5
  • 6

4 Answers4

31

Actually I prefer a third form:

Console.WriteLine("{0:N}", val / 1085);

Console.WriteLine can do the String.Format for you.

Console.WriteLine does not allow you to supply a culture. If that is what you want, you will still have to use String.Format. As in:

String.Format(CultureInfo.InvariantCulture, "{0:N}", 123456789);

I do not recommend using that because international users will have trouble reading that. To me 123,456,789.00 looks strange.

heijp06
  • 11,558
  • 1
  • 40
  • 60
4

For formatting + culture I prefer:

 .ToString("####0.00",CultureInfo.InvariantCulture)

or

.ToString("N",CultureInfo.InvariantCulture)
Julian de Wit
  • 3,084
  • 2
  • 29
  • 29
3

I found an invariant and generic way to solve that.

Syntax:

.ToStringInvariant(format)
.ToStringInvariant() 

Technically, it is a generic extension method, defined as follows:

public static class Extensions
{
    private static IFormatProvider inv 
                   = System.Globalization.CultureInfo.InvariantCulture.NumberFormat;

    public static string ToStringInvariant<T>(this T obj, string format=null)
    {
        return (format == null) ? System.FormattableString.Invariant($"{obj}") 
                                : String.Format(inv, $"{{0:{format}}}", obj);
    }
}

Usage is simple, just use .ToStringInvariant() instead of .ToString(). The advantage is that it works for any data type.

Optionally, you can pass a format too, like for example .ToStringInvariant("N"), just as you are used to to it with .ToString("N"). Note that in that case the extension method uses String.Format internally.

You can see the difference if you have a different culture for the number format, like in Germany we have comma instead of a decimal point. That means on a PC with German culture settings:

void Main()
{
    var val = 2456.5;
    Console.WriteLine((val/1085).ToString("N"));
    Console.WriteLine((val/1085).ToStringInvariant("N"));
    Console.WriteLine((val/1085).ToStringInvariant("0.000"));
    Console.WriteLine((val/1085).ToStringInvariant());
}

it would output:

2,26
2.26
2.264
2.26405529953917

which is correct, because .ToString uses the current culture (German settings), and .ToStringInvariant always uses the invariant culture, which is the English number format regardless of the Windows settings.

Note: Especially for date formatting, I have provided a different extension method, which you can find here.


More information: FormattableString.Invariant(FormattableString) Method

Matt
  • 25,467
  • 18
  • 120
  • 187
  • This is equivalent to using `.ToString()` but the question is asking about `.ToString("N")`. Your string interpolation should be like this: `$"{obj:N}"`. (Maybe you'd want to pass format "N" as a parameter though.) – intrepidis Apr 03 '20 at 08:51
  • @intrepidis - Good point, I have improved the extension method so you can now do that too. – Matt Apr 03 '20 at 09:13
1

In a datetime it's okay to use both. I rather like to use and see the first solution (ofcourse with missing parenthesis).

The String.Format is much more usefull when you have some string with a gaps for some kind of parameters. Then it's a killer method, which really nicely help you to organize your code.

Łukasz W.
  • 9,538
  • 5
  • 38
  • 63