无论当前环境如何,我都想确保我的应用程序中的某些数字在打印时没有任何分隔符、分组等。似乎以下两种方法产生相同的结果(可能更多):
123456789.ToString("0");
123456789.ToString(CultureInfo.InvariantCulture);
您是否知道任何边缘情况或怪癖?哪个更“正确”?你会用哪一个?
我曾经使用第二个,但最近我找到了第一个并开始使用它,因为它不需要额外的using System.Globalization
.
无论当前环境如何,我都想确保我的应用程序中的某些数字在打印时没有任何分隔符、分组等。似乎以下两种方法产生相同的结果(可能更多):
123456789.ToString("0");
123456789.ToString(CultureInfo.InvariantCulture);
您是否知道任何边缘情况或怪癖?哪个更“正确”?你会用哪一个?
我曾经使用第二个,但最近我找到了第一个并开始使用它,因为它不需要额外的using System.Globalization
.
根据此处的答案和讨论,我进行了更多调查。这是我发现的:
当您12345678.ToString()
不带任何参数使用时,.NET 使用一般格式说明符“G”,它仅受 NumberFormatInfo.NegativeSign、NumberFormatInfo 影响。NumberDecimalSeparator、NumberFormatInfo.NumberDecimalDigits 和 NumberFormatInfo.PositiveSign。对我来说,这表明在任何文化中12345678.ToString()
都应该始终产生“12345678”。
如果要分隔数字,则需要使用数字格式说明符“N”(或者,当然,提供自定义格式字符串)。数字分组也适用于“C”和“P”。
不变的文化确实指定了数字分组(当然是 3 位数字)和数字分隔符。所以123456789.ToString(CultureInfo.InvariantCulture)
产生“123456789”的原因不是因为文化不变,而是因为默认的通用数字格式说明符“G”。
所以我会说结论是完全可以不用担心任何额外的参数而只需使用:
12345678.ToString()
我认为这是所有情况中最好的,因为这意味着通常您甚至不需要调用ToString()
,因为大多数打印/写入函数都接受各种参数并ToString()
为您执行。
The two methods are not equivalent: the first is using the CurrentCulture
. This could lead to extra dots/commas in certain cultures (I don't have examples).
When you use InvariantCulture
you are certain that always the same formatting is used.
Edit: And, if you use CodeAnalysis, that will complain when you don't use a CultureInfo
.
.ToString()和.ToString(CultureInfo.InvariantCulture)似乎对整数给出了相同的结果。
下面的代码在我的 PC 上给出了“测试了 809 种文化,发现了 0 种差异”的结果(对于 .NET Framework 4.7.2):
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures).ToArray();
var numbers = new[] { 0, -1, 1, int.MinValue, int.MaxValue };
var diffsFound = 0;
foreach (var culture in cultures)
{
foreach (var number in numbers)
{
var s1 = number.ToString();
var s2 = number.ToString(culture);
if (s1 != s2)
{
Console.WriteLine($"{culture.DisplayName}: {s1} != {s2}");
diffsFound++;
}
}
}
Console.WriteLine($"{cultures.Length} cultures tested, {diffsFound} differences found.");
(约 5 年后...)
我正在查找这个确切的问题,但由于没有公认的答案,即使 Jan Zich 是正确的,我想我会整理一个小例子来测试这个。
我还要说 .ToString()、.ToString("0") 和 .ToString(Any Culture Info) 之间没有区别(就整数和小数而言)
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures)
.Except(CultureInfo.GetCultures(CultureTypes.SpecificCultures));
foreach(var c in cultures){
var num = (int.MinValue);/*
var num = (int.MaxValue);/*
var num = (decimal.MinValue);/*
var num = (decimal.MaxValue);/*
--*/
var s1 = num.ToString("0") ;
var s2 = num.ToString(c);
if(s1 != s2){
var s = string.Format("{2}: {0} {1}",s1,s2,c);
s.Dump();
}
}
As I see it, The first one will format is a number with at least one character using the default culture of the computer. The second will format it as a number depending on the InvariantCulture rules.
Bobby
2行做不同的事情。第一行使用本地文化对数字进行格式化,第二行将其转换为字符串而不进行格式化,但使用 CultureInfo.InvariantCulture。
您将 CultureInfo.InvariantCulture 与此类方法(ToString、ToLower ...)一起使用,以确保当任何软件(数据库、另一个库 ...)使用该值时,无论其文化是什么,都会导致相同的值,当他们可以获取该值时,他们可以继续处理它。但是,如果您不使用它,则其他软件必须弄清楚您的文化是什么。你的意思是用逗号或其他东西的小数分隔符......?
当您想在库、数据库之间交换/使用值并使用 CultureInfo.CurrentCulture 向应用程序的用户展示时,所有和所有都使用 CultureInfo.InvariantCulture。
// for softwares
string mystring1 = 1234.ToString("0", CultureInfo.InvariantCulture);
// for your application users
string mystring2 = 1234.ToString("0", CultureInfo.CurrentCulture);
If you're wanting to make sure to specify "no formatting, no matter what" I personally think the first option you have:
123456789.ToString("0");
better communicates the intent. The downside would be if a culture overrode the format string of "0" for the numeric type you are using.