1

I have prepared a C# fiddle for my question, however it does not really show the actual problem and correctly uses dots as decimal separator in the interpolated double values (UPDATED with Tim's trick, thank you):

using System;
using System.Linq;

public class Program
{
    readonly static (double lng, double lat)[] Locations = 
    {
        (10.757938, 52.437444),
        (10.764379, 52.437314),
        (10.770562, 52.439067),
        (10.773268, 52.436633),
    };
    
    public static void Main()
    {
        string lngLats = Locations.Aggregate(string.Empty, (str, next) => str + $"{next.Item1:F6},{next.Item2:F6};");
        Console.WriteLine($"lngLats: {lngLats}\n");
        
        double x = 12.3456;
        Console.WriteLine($"A double value: {x}\n");
    }
}

However, when I run the same code on my Windows 10 Enterprise 22H2 computer, (set to English language, but German region) using Visual Studio 2022, then the decimal separator is a comma:

screenshot VS 2022

My question is: how to ensure that the decimal separator character is always a dot in the interpolated strings?

Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
  • 1
    If you change your fiddle to include this as first line, you can reproduce it there too: `System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de-DE");` – Tim Schmelter Jul 19 '23 at 14:03

3 Answers3

2

String interpolation uses the current culture. So you need a workaround with double.ToString:

double x = 12.3456;
string result = x.ToString(System.Globalization.CultureInfo.InvariantCulture);
Console.WriteLine($"A double value: {result}\n");

Your modified fiddle: https://dotnetfiddle.net/BTaONq

So string interpolation doesn't support a different culture. You could use string.Format:

Console.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "A double value: {0}\n", x));
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Sure Tim, I have seen the suggestion on `ToString` method while searching for a solution... but my question is if there is some trick to make the string interpolation always use a dot. – Alexander Farber Jul 19 '23 at 14:08
  • @AlexanderFarber: nope. Then you need to use `String.Format`. Added that to my answer – Tim Schmelter Jul 19 '23 at 14:08
  • 2
    Wouldn't it work to set the current Culture, though? Like in your comment to the question, @TimSchmelter, only set it to Invariant? – Fildor Jul 19 '23 at 14:14
  • @Fildor-standswithMods: Sure, that would work. But it has more impact, OP just want to modify this single string and not change the culture.What is the benefit over simply using the right tool(`double.ToString`)? – Tim Schmelter Jul 19 '23 at 14:15
  • Yes, I guess that would have some possibly unwanted side-effects... – Fildor Jul 19 '23 at 14:15
  • Thank you, Tim. But I think anyone agrees, that the `Console.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, "A double value: {0}\n", x));` is a horribly long code line for printing a very simple string... – Alexander Farber Jul 19 '23 at 14:18
  • An extension method is off the table? – Fildor Jul 19 '23 at 14:19
  • 2
    @AlexanderFarber: well, no need to use the full namespace, `CultureInfo.InvariantCulture` is enough, but i agree that this is not so nice than using string interpolation. I would add another line for the double.ToString and then use it in the interpolated string. That makes it very clear and readable(also in the debugger). But if you like one-liners you can also use `x.ToString(CultureInfo.InvariantCulture)` in the string, so `Console.WriteLine($"A double value: {x.ToString(CultureInfo.InvariantCulture)}\n");` – Tim Schmelter Jul 19 '23 at 14:21
2

You can use the invariant culture like this

string result1 = FormattableString.Invariant($"lngLats: {lngLats}\n");
string result2 = FormattableString.Invariant($"A double value: {x}\n");

With a using static System.FormattableString; you can simplify the calls and of course you can integrate this with the console output:

string lngLats = Locations.Aggregate(
    string.Empty,
    (str, next) => str + Invariant($"{next.Item1:F6},{next.Item2:F6};")
);
Console.WriteLine($"lngLats: {lngLats}\n");

double x = 12.3456;
Console.WriteLine(Invariant($"A double value: {x}\n"));

See also:

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
1

I was thinking about this compromise, maybe?

double x = 12.3456;
Console.WriteLine($"A double value: {x.AsInvariant()}\n");

// with

public static string AsInvariant(this double x) =>
   x.ToString(System.Globalization.CultureInfo.InvariantCulture);
Fildor
  • 14,510
  • 4
  • 35
  • 67
  • 1
    You could simply use `$"A double value: {x.ToString(CultureInfo.InvariantCulture)}\n"` which i like more, because everyone sees what it's doing. – Tim Schmelter Jul 19 '23 at 14:26
  • While I agree, OP wanted something shorty short ... I don't think this will leave us with a clean _and_ satisfying answer, I am afraid. – Fildor Jul 19 '23 at 14:28