2009-09-28 97 views
13

我想确保我的应用程序中的某些数字在没有任何分隔符,分组等的情况下打印,不管当前的环境是什么。看来以下两种方法产生的结果相同(可能更多):ToString(“0”)与ToString(CultureInfo.InvariantCulture)

123456789.ToString("0"); 
123456789.ToString(CultureInfo.InvariantCulture); 

您是否知道任何边缘情况或怪癖?哪一个更“正确”?你会用哪一个?

我曾经使用第二个,但最近我发现第一个,并开始使用它,因为它不需要额外的using System.Globalization

回答

0

如果你想确保指定“无格式,不管是什么”我个人认为第一个选项,您有:

123456789.ToString("0"); 

更好的通信的意图。不利的一面是,如果文化覆盖了您所使用的数字类型的格式字符串“0”。

+0

哦,我现在也知道,你可以重写格式字符串?我需要查看它。 – 2009-09-28 15:07:36

+0

你确定超载吗? MSDN(http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx)说:“任何其他单个字符[比那些标准之一]在运行时抛出一个FormatException。” – 2009-09-28 15:26:09

+0

我不确定这是否是这种情况。我看到一个MSDN库的快速访问会显示给我:)。 – 2009-09-28 15:38:22

2

正如我所看到的,第一个格式是一个数字,至少有一个字符使用计算机的默认文化。 第二个将根据InvariantCulture规则将其格式化为数字。

巴比

+0

纠正我,如果我错了:我认为没有数字分组,分隔符等适用于123456789.ToString(“0”)? – 2009-09-28 15:10:17

+0

呃......它真的没有。我错误地认为它是一种格式化符号,如“N0”,它符合当前的文化规则。你是对的,因为0是直接格式化,它不适用_any_文化信息。 虽然有人也可以使用123456789.ToString(); 。 – Bobby 2009-09-29 07:13:51

5

这两种方法是不等价的:第一是使用的CurrentCulture。这可能会导致某些文化中的额外点/逗号(我没有示例)。

当您使用InvariantCulture时,您确定始终使用相同的格式。

编辑:而且,如果您使用CodeAnalysis,那么当您不使用CultureInfo时会抱怨。

+0

我通过修改当前的线程文化测试了第一个线程,并且没有影响到它。我认为“0”意味着:至少有一个数字+无数字分组或分隔符。如果我想要一些数字分组或分隔符,我想我必须做一些像“000,000”的事情。 – 2009-09-28 15:14:19

+2

但是你是对的:InvariantCulture“听起来”更加明确。即使MSDN也说“......它与英语有关,但与任何国家/地区都没有关系”。嗯,当我考虑更多的时候,ToString(CultureInfo.InvariantCulture),这意味着数字如果使用“G”格式化。这一切都恰好适用,因为“G”似乎没有使用任何分组。但(我只是看了起来)不变的文化有一些指定的分组。例如,尝试12345789.ToString(“N”,CultureInfo.InvariantCulture)。 – 2009-09-28 15:23:49

17

基于这里的答案和讨论,我做了更多的调查。以下是我发现:

  • 当您使用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”。

所以,我要说的是,结论是,这是完全OK 不用担心任何额外的参数,只是使用

12345678.ToString() 

我认为这从所有情况下,最好的因为这意味着你通常不需要拨打ToString(),因为大部分打印/写入功能都可以接受各种参数,并为你做ToString()

1

2行做不同的事情。第一行用本地文化格式化数字,第二行将格式转换为字符串,但使用CultureInfo.InvariantCulture。

您可以使用CultureInfo.InvariantCulture和这种方法(ToString,ToLower ...)来确保当值被任何软件(数据库,另一个库...)使用时,不管他们的文化是什么,它会得到相同的值,并且当它们可以拿起这个值时,它们可以继续处理它。但是,如果你不使用这个,其他软件必须弄清楚你的文化是什么。你的意思是用逗号或其他东西来表示小数点吗?

全部和全部使用CultureInfo.InvariantCulture当你想在库,数据库之间交换/使用值,并使用CultureInfo.CurrentCulture向你的应用程序的用户显示。

// for softwares 
string mystring1 = 1234.ToString("0", CultureInfo.InvariantCulture); 

// for your application users 
string mystring2 = 1234.ToString("0", CultureInfo.CurrentCulture); 
1

(〜5年后...)

我一直在寻找了这个确切的问题,但由于没有公认的答案和即使扬Zich是正确的,我想我会放在一起一点点例子来测试这个。

我还会去说迄今为止.ToString(),.ToString(“0”)和.ToString(任何文化信息)之间没有区别(就整数和小数而言)

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(); 
    } 
} 

LinqPad snippet

0

的ToString()的ToString(CultureInfo.InvariantCulture)总是给出整数相同的结果。下面

代码给“809文化测试,0差异发现”结果我的电脑上:

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.");