2009-09-28 4 views
13

Я хотел бы удостовериться, что определенные числа в моем приложении печатаются без каких-либо разделителей, групп и т. Д., Независимо от текущей среды. Представляется, что следующие два метода дают одинаковые результаты (есть, возможно, больше):ToString («0») по сравнению с ToString (CultureInfo.InvariantCulture)

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

Вы знаете о каких-либо крайних случаях или причуды? Какой из них более «правильный»? Какой из них вы бы использовали?

Я использовал второй, но недавно я нашел первый и начал использовать его, потому что он не требует дополнительных using System.Globalization.

ответ

0

Если Вы желаете, чтобы убедиться, чтобы указать «нет форматирования, независимо от того, что» я лично думаю, что первый вариант у вас есть:

123456789.ToString("0"); 

лучше передает намерение. Недостатком было бы то, что культура перевернула строку формата «0» для используемого числового типа.

+0

О, я теперь знаю, что вы можете изменить строки форматирования? Мне нужно посмотреть. –

+0

Ты уверен в себе перегрузка? MSDN (http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx) говорит: «Любой другой единственный символ [, чем один из этих стандартных] генерирует исключение FormatException во время выполнения». –

+0

Я не был уверен, было ли это так или нет. Я вижу, что быстрая поездка в библиотеку MSDN показала бы мне :). –

2

Как я вижу, первый формат будет содержать число с хотя бы одним символом, использующим культуру по умолчанию компьютера. Второй будет отформатировать его как число в зависимости от правил InvariantCulture.

Бобби

+0

Исправьте меня, если я ошибаюсь: я думал, что никакая группировка цифр, разделитель и т. Д. Не применяются к 123456789.ToString («0»)? –

+0

Уххх ... это действительно не так. Я ошибаюсь для символа форматирования, такого как «N0», который применяет текущие правила культуры. Вы правы, так как 0 - прямое форматирование, оно не применяет _any_ информацию о культуре. Хотя, кто-то может также использовать 123456789.ToString(); , – Bobby

5

Эти два метода не являются эквивалентными: первый использует CurrentCulture. Это может привести к дополнительным точкам/запятым в определенных культурах (у меня нет примеров).

Когда вы используете InvariantCulture, вы уверены, что всегда используется одно и то же форматирование.

Редактировать: И если вы используете CodeAnalysis, это будет жаловаться, если вы не используете CultureInfo.

+0

Я проверил первый, изменив текущую культуру потока, и это не повлияло на нее. Я думаю, что «0» означает: по крайней мере одну цифру + без группировки цифр или разделителей. Если бы я хотел иметь некоторую цифровую группировку или разделители, я думаю, что мне нужно было бы сделать что-то вроде «000 000». –

+2

Но вы правы: InvariantCulture «звучит» более четко. Даже MSDN говорит: «... это связано с английским языком, но не с какой-либо страной/регионом». Хм, когда я думаю о более, ToString (CultureInfo.InvariantCulture), это означает, что число, если отформатировано с помощью «G». Все это просто срабатывает ТОЛЬКО, потому что «G», похоже, не использует какую-либо группировку. НО (я просто посмотрел), в инвариантной культуре есть определенная группа. Например, попробуйте 12345789.ToString («N», CultureInfo.InvariantCulture). –

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».

Так что я бы сказал, что вывод о том, что это совершенно нормально не беспокоиться о каких-либо дополнительных аргументов и просто использовать:

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."); 
Смежные вопросы