Ответ
Правильная плюрализация — это не просто добавление 's'. В разных языках разное количество форм для множественного числа (например, в русском 3, в арабском — 6). Решение должно быть основано на стандартах ICU (Unicode).
1. Использование библиотеки Humanizer (Рекомендуемый подход)
Humanizer поддерживает множество языков и склонений, предоставляя простой API.
// Установите пакет: Install-Package Humanizer
using Humanizer;
// Плюрализация на английском
"apple".Pluralize(1); // "apple"
"apple".Pluralize(2); // "apples"
// Плюрализация на русском (требует установки культуры)
var culture = new System.Globalization.CultureInfo("ru-RU");
"сообщение".Pluralize(1, culture); // "сообщение"
"сообщение".Pluralize(2, culture); // "сообщения"
"сообщение".Pluralize(5, culture); // "сообщений"
// Форматирование строк с числительными
"Message".ToQuantity(5, ShowQuantityAs.Words); // "five messages" (en)
2. Использование .resx файлов с выбором формы по правилам
Для полного контроля можно хранить шаблоны в ресурсах, а выбор осуществлять по формуле. Для русского языка часто используется формула:
string GetRussianPluralForm(int number, string form1, string form2, string form5)
{
number = Math.Abs(number) % 100;
int n1 = number % 10;
if (number > 10 && number < 20) return form5;
if (n1 > 1 && n1 < 5) return form2;
if (n1 == 1) return form1;
return form5;
}
// В ресурсном файле Messages.ru.resx:
// PluralForm1: "{0} сообщение"
// PluralForm2: "{0} сообщения"
// PluralForm5: "{0} сообщений"
int count = 5;
string form = GetRussianPluralForm(count, PluralForm1, PluralForm2, PluralForm5);
string result = string.Format(form, count); // "5 сообщений"
3. Использование IStringLocalizer и Plural в ASP.NET Core
В современных приложениях ASP.NET Core фреймворк предоставляет встроенные средства.
// В ресурсном файле (например, Resources.ru.resx) можно использовать параметризованные ключи.
// На практике часто используют библиотеки, подобные `SmartFormat` или `MessageFormatter`,
// которые поддерживают плюрализацию по стандарту ICU прямо в строке шаблона.
// Пример со SmartFormat (пакет SmartFormat.NET)
using SmartFormat;
var message = Smart.Format("{0} {0:сообщение|сообщения|сообщений}", count);
4. Ключевые принципы:
- Не изобретайте велосипед: Для поддержки многих языков используйте проверенные библиотеки (
Humanizer,SmartFormat). - Отделяйте данные от шаблона: Число и строковый шаблон должны быть независимы.
- Тестируйте на пограничных значениях: 0, 1, 2, 5, 11, 21, 101.
- Учитывайте контекст: Иногда фраза "1 file(s) processed" лучше, чем сложная система склонений для редких языков в MVP.