双 ToString 保持 "en-US" 格式

Double ToString keeping "en-US" format

听起来很简单 - 我知道它是......但我遇到了问题并且不知道为什么......

我有一个全球化的网络应用程序(多语言)。 当我点击更改语言时,这是我的操作:

public ActionResult ChangeCulture(string lang)
{
    Thread.CurrentThread.CurrentCulture = new CultureInfo(lang);
    Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

    var languageCookie = new HttpCookie("_language") { Value = lang, Expires = DateTime.UtcNow.AddYears(1) };

    Response.Cookies.Remove("_language");
    Response.SetCookie(languageCookie);

    return Redirect(Request.UrlReferrer.PathAndQuery);
}

我有一个页面可以显示一些字符(我正在使用 chart.js),我需要将 List<double> 绑定到 javascript 数组。

所以这个列表看起来像:

var list = new List<double> {144, 0, 540.23};

我需要一个简单数组 javascript:

var arr = [144, 0, 540.23];

这是我的做法(剃须刀):

var arr = [@string.Join(",", Model.ListWithDoubles.Select(x => Convert.ToString(x, new CultureInfo("en-US"))))]

问题是:

当我使用英语时,它的效果很好。其他语言给我的是整数...

var arr = [144, 0, 540.23]; //en-US
var arr = [144, 0, 54023]; //pt-BR 
var arr = [144, 0, 54023]; //it
var arr = [144, 0, 54023]; //es

问题

  1. 为什么?
  2. 如何修复?

因为在其他一些非 en-US 文化中,,. 具有完全相反的含义和用法。如果您不显示此数据,仅用于图表目的,则在将 HTML 的双精度转换为字符串表示时使用 CultureInfo.InvariantCulture。您应该只在您想要实际以可视方式向用户显示该数据值时转换为特定于文化的字符串。

var arr = [@string.Join(",", Model.ListWithDoubles.Select(x => Convert.ToString(x, CultureInfo.InvariantCulture)))]

double 的默认格式说明符是 G,因此它将创建仅包含小数点分隔符的输出。由于您想要原始数字(未格式化显示),因此您需要传递此 (CultureInfo.InvariantCulture),而不是仅用于显示的区域性格式化字符串表示形式。


为了说明我发布的代码无论当前线程的文化如何,这里都是该代码。将其放入控制台应用程序并替换 Main 方法和 运行 方法。你会看到这是有效的。您的问题出在别处,与此代码无关。

static void Main(string[] args)
{
    var cultures = new[] {"en-US", "pt-BR", "it", "es"};
    var list = new List<double> {144, 0, 540.23};

    Console.WriteLine("Without specifying a culture");

    foreach (var culture in cultures.Select(isoCulture => new CultureInfo(isoCulture)))
    {
        System.Threading.Thread.CurrentThread.CurrentCulture = culture;
        System.Threading.Thread.CurrentThread.CurrentUICulture = culture;

        Console.WriteLine("Culture: " + culture.Name);

        Console.WriteLine("Not defined:                  " + string.Join(",", list.Select(x => Convert.ToString(x))));
        Console.WriteLine("CultureInfo.InvariantCulture: " + string.Join(",", list.Select(x => Convert.ToString(x, CultureInfo.InvariantCulture))));
    }
    Console.ReadLine(); // stops so you can see the results
}