Множественность сообщений пользователей

106

Часто при создании сообщений для показа пользователю сообщение будет содержать ряд вещей, о которых я хочу сообщить клиенту.

Я приведу пример: клиент выбрал несколько элементов от 1 и выше и нажал кнопку «Удалить». Теперь я хочу отправить покупателю подтверждающее сообщение и упомянуть количество выбранных им элементов, чтобы свести к минимуму вероятность того, что он совершит ошибку, выбрав несколько элементов и нажав кнопку «Удалить», когда он хочет удалить только один из них. их.

Один из способов - сделать общее сообщение таким:

int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " item(s). Are you sure you want to delete it/them?";

«Проблема» здесь в том, что noofitemselectedэто 1, и мы должны написать item и it вместо items и них .

Мое обычное решение будет примерно таким

int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " " + (noofitemsselected==1?"item" : "items") + ". Are you sure you want to delete " + (noofitemsselected==1?"it" : "them") + "?";

Это становится довольно длинным и довольно неприятным, очень быстро, если в коде много ссылок на множество чисел, а фактическое сообщение становится трудно читать.

Так что мои вопросы просты. Есть ли лучшие способы создания подобных сообщений?

РЕДАКТИРОВАТЬ

Я вижу, что многие люди очень зациклились на том случае, когда я упомянул, что сообщение должно отображаться внутри окна сообщения, и просто дал ответ о том, как вообще избежать использования окна сообщения, и это все хорошо .

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

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

Эйвинд Братен
источник
6
@ 0xA3: я действительно не знаю, есть ли в каждом языке множественное число, которое так же легко выражается как «элемент (ы)».
Jens
5
Возможно, вам стоит подумать и о локализации. Эта проблема может стать намного хуже.
Alex Brown
4
@Jens: Обычно они этого не делают, наименее удобным способом. Некоторые языки имеют, например, разные формы множественного числа для 2-4, чем для 5-бесконечности, и все это зависит от пола. "Естественные языки: безумие локализации! Скоро на компьютере рядом с вами!"
Писквор покинул здание
29
ИМО, ничто не заставляет программистов выглядеть более ленивыми для пользователей, чем плохое множество.
Грег
4
@ Øyvind: +1 за ваше редактирование. Похоже, что многие из «ответивших» здесь больше стремятся доказать, что ваш вопрос неправильный, чем предложить правильное решение. Анти-решения, если хотите.
mwolfe02

Ответы:

53

Если есть шанс, даже самый маленький, что это приложение нужно будет перевести на другие языки, то оба они ошибаются. Правильный способ сделать это:

string message = ( noofitemsselected==1 ?
  "You have selected " + noofitemsselected + " item. Are you sure you want to delete it?":
  "You have selected " + noofitemsselected + " items. Are you sure you want to delete them?"
);

Это связано с тем, что разные языки по-разному обрабатывают множественность. Некоторые, такие как малайский, даже не имеют синтаксических множественных чисел, поэтому строки обычно идентичны. Разделение двух строк упрощает поддержку других языков в дальнейшем.

В противном случае, если это приложение предназначено для широкой публики и должно быть удобным для пользователя, предпочтительнее второй метод. Извините, но я не знаю более короткого способа сделать это.

Если это приложение предназначено для использования только внутри вашей компании, сделайте это с помощью ярлыка "item(s)". При написании предприимчивого кода не нужно никого впечатлять. Но я бы не советовал делать это для общедоступных приложений, потому что это создает впечатление, что программист ленив, и, таким образом, снижает их мнение о качестве приложения. Поверьте мне, такие мелочи имеют значение.

слебетман
источник
35
Хотя я согласен с посылкой, вы игнорируете языки, которые имеют более двух степеней множественности. (Возьмем, к примеру, русский язык. Три разных способа сказать, в зависимости от того, 1, <5 или> = 5, и даже это зависит от того, о чем именно вы говорите). По сути, я говорю, что вам нужен более сильный условный оператор, а не только тернарный оператор.
авария
4
В noofitemsselectedэтом примере вы даже можете оптимизировать первый вариант; поскольку вы знаете, что это 1.
Default
16
В то время как мы это делаем, иврит может иметь разные множественные числа для 1, 2, 3-10 и 11+.
Джоэл Спольски
3
@ Джоэл, в иврите может быть столько разных множественных чисел? לא ידעתי (не знала)! Современный иврит во множественном числе похож на английский (хотя древний иврит также имел двойную форму)
Кен Блум,
3
В английском языке ноль воспринимается как множественное число (0 элементов, 2 элемента); что происходит с нулем на иврите, русском, румынском? Есть ли простой способ определить диапазоны? Я предполагаю, что информация должна определяться для каждого языка, поэтому любые системы, основанные на файлах сообщений, должны иметь дело с различным количеством множества сообщений в наборе сообщений. Ой! Настройка переводов тоже будет сложной задачей - для разных языков требуется разное количество сообщений.
Джонатан Леффлер,
94

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

На самом деле вы получаете 2 преимущества, когда создаете комплексную возможность отмены. Первое преимущество облегчает жизнь пользователя, позволяя ему исправить ошибки и свести к минимуму чтение. Второе преимущество заключается в том, что ваше приложение отражает реальную жизнь, позволяя отменить нетривиальный рабочий процесс (а не только ошибки).

Однажды я написал приложение без единого диалогового окна или подтверждающего сообщения. Это потребовало серьезного размышления и было значительно труднее реализовать, чем использование сообщений типа подтверждения. Но конечный результат был довольно приятным для использования конечными пользователями.

HTTP 410
источник
12
По какой-то причине мне кажется, что я согласен с этим и должен проголосовать за него.
Коди Грей
4
@ Øyvind, вот почему: сообщения, запрашивающие у пользователя подтверждение, дороги для пользователя, особенно когда они представлены в виде модального диалогового окна, которое останавливает все, пока пользователь не ответит на диалог. Это раздражает многих пользователей до такой степени, что они начинают просто нажимать любую кнопку, чтобы выйти из диалогового окна (сколько установщиков вы только что щелкнули следующим, следующим, следующим? ). Следовательно, это безопаснее и меньше проблем с пользователем, если вы просто выполняете мягкое удаление и обеспечиваете возможность отмены. Gmail использует этот метод с большим успехом.
Роберт Харви,
5
Спорный, но в любом случае та же проблема возникнет в случаях, отличных от сообщения с подтверждением удаления, поэтому этот ответ действительно не имеет отношения к вопросу.
Джей
50
Я проголосовал за это, но не читал. Я всегда могу отменить это позже
Стивен А. Лоу
6
@ Роберт Харви: Наверное, апокриф, но много лет назад я читал, что Lotus отправила 40 000 единиц Lotus Notes для Mac и 60 000 были возвращены. Интерфейс был настолько плохим, что даже пираты отправили его обратно.
Дункан
39

Как насчет только:

string message = "Are you sure you want to delete " + noofitemsselected + " item(s)?"

Таким образом вы устраняете трудности с согласованием номеров и получаете в качестве бонуса еще более короткое и конкретное сообщение об ошибке для пользователя. Все мы знаем, что пользователи все равно не читают сообщения об ошибках . Чем они короче, тем больше вероятность, что они хотя бы взглянут на текст.

Или, зная, что пользователи не читают сообщения об ошибках, вы можете подойти к этому по-другому. Полностью пропустите подтверждающее сообщение и просто предоставьте функцию отмены, которая работает, независимо от того, что было удалено. Большинство пользователей уже привыкли отменять операцию, когда замечают, что это было не то, что они хотели, и, вероятно, сочтут такое поведение более естественным, чем иметь дело с очередным раздражающим всплывающим окном.

Коди Грей
источник
1
Хороший ответ. Однако в данном случае заказчик попросил предоставить сообщения об ошибках для многих многих случаев, потому что он считал, что это лучший подход. Но изменение текста может, по крайней мере, минимизировать проблему и сделать ее менее беспорядочной.
Øyvind Bråthen
@ Эйвинд: Достаточно честно. Поскольку вы должны следовать за клиентом, я бы выбрал первый предложенный мной подход или использовал файл ресурсов с функцией обработчика. Я просто подумал, что стоит указать на альтернативу, потому что о ней так легко забыть. Черт возьми, я даже не подумал об этом, пока не отправил свой первый ответ.
Коди Грей
Альтернативы приветствуются. Вот почему я тоже поставил +1 :)
Øyvind Bråthen
1
+1 за то, что не пытался решить неразрешимую проблему. И помните закон Стива Круга: уберите половину слов. Затем сделайте это снова. Я использую: "Удалить {x} элементов?"
Серж Вотье
20

А как насчет того, что было в Java на протяжении многих лет: java.text.MessageFormat и ChoiceFormat? См. Http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html для получения дополнительной информации.

MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
form.applyPattern(
   "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");

Object[] testArgs = {new Long(12373), "MyDisk"};

System.out.println(form.format(testArgs));

// output, with different testArgs
output: The disk "MyDisk" are no files.
output: The disk "MyDisk" is one file.
output: The disk "MyDisk" are 1,273 files.

В вашем случае вам нужно что-то попроще:

MessageFormat form = new MessageFormat("Are you sure you want to delete {0,choice,1#one item,1<{0,number.integer} files}?");

Преимущество этого подхода заключается в том, что он хорошо работает с пакетами i18n, и вы можете правильно предоставлять переводы для языков (например, японского), которые не имеют понятия слова во множественном или единственном числе.

Берин Лорич
источник
1
Этот подход хорошо работает с множественностью, но, к сожалению, не учитывает гендер. Вам нужны разные строки для каждого типа вещей, которые можно удалить.
Мистер Блестящий и Новый 安
Если вы знаете существительное, вы можете строить предложения так, чтобы они работали с подходящим прилагательным. Но да, изучив классический греческий язык, у вас есть другая форма слова, основанная на существительных мужского, женского или среднего рода (прилагательное принимает форму существительного, которое оно изменяет), и эта форма отличается в зависимости от его функции в предложении ( субъект, объект и т. д.). Мы всегда можем придумать случаи, когда одно решение работает, а другое - нет. Именно так разработчики Java попытались решить проблему. Вы по-прежнему должны быть осторожны с тем, как вы формируете форматы сообщений.
Берин Лорич
Вы всегда можете скормить решению Java два целых числа, где второе указывает пол. (Но на самом деле гендерное согласие обычно не вызывает беспокойства просто потому, что пример использования различных объектов в сообщении встречается реже, чем установка разных номеров одного и того же объекта в сообщение)
Кен Блум,
12

Я бы не стал жестко кодировать сообщение, но предоставил два сообщения в отдельном файле ресурсов. подобно

string DELETE_SINGLE = "You have selected {0} item. Are you sure you want to delete it?";
string DELETE_MULTI = "You have selected {0} items. Are you sure you want to delete them?";

а затем подавать их в String.Format, например

if(noofitemsselected == 1)
    messageTemplate = MessageResources.DELETE_SINGLE;
else
    messageTemplate = MessageResources.DELETE_MULTI;

string message = String.Format(messageTemplate, noofitemsselected)

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

Йенс
источник
+1, мне нравится такой подход. Хотя вам нужно будет отслеживать эквиваленты имен ресурсов.
Default
11

Вы можете полностью обойти проблему, сформулировав сообщение иначе.

string message = "The number of selected items is " + noofitemsselected + ". Are you sure you want to delete everything in this selection?";
Gdejohn
источник
10

Первое, что я предлагаю: использовать string.Format. Это позволяет делать что-то вроде этого:

int numOfItems = GetNumOfItems();
string msgTemplate;
msgTemplate = numOfItems == 1 ? "You selected only {0} item." : "Wow, you selected {0} items!";
string msg = string.Format(msgTemplate, numOfItems);

Кроме того, в приложениях WPF я встречал системы, в которых строка ресурса была бы разделена каналом, чтобы иметь два сообщения: единственное и множественное сообщение (или даже сообщение ноль / одно / много). Затем можно использовать настраиваемый конвертер для анализа этого ресурса и использования соответствующей (отформатированной) строки, поэтому ваш Xaml будет примерно таким:

<TextBlock Text="{Binding numOfItems, Converter={StaticResource c:NumericMessageFormatter}, ConverterParameter={StaticResource s:SuitableMessageTemplate}}" />
Дэн Пьюзи
источник
7

Для английского много ответов выше. Для других языков это сложнее, так как множественное число зависит от рода существительного и окончания слова. Некоторые примеры на французском:

Обычный мужской род:

Vous avez choisi 1 compte. Voulez-vous vraiment le supprimer.
Vous avez choisi 2 comptes. Voulez-vous vraiment les supprimer.

Обычный женский

Vous avez choisi 1 table. Voulez-vous vraiment la supprimer.
Vous avez choisi 2 tables. Voulez-vous vraiment les supprimer.

Нерегулярный мужской род (заканчивается буквой s)

Vous avez choisi 1 pays. Voulez-vous vraiment le supprimer.
Vous avez choisi 2 pays. Voulez-vous vraiment les supprimer?

Та же проблема существует в большинстве латинских языков и усугубляется в немецком или русском, где есть 3 пола (макулиновый, женский и средний).

Вам нужно будет позаботиться о том, чтобы заниматься не только английским языком.

ухмыляющийся человек
источник
По крайней мере, в моем случае это не проблема. Для каждого текста, в который я хочу вставить число, я буду знать, что такое существительное при генерации строки. Но чтобы принять более общее решение, я согласен с вами, что заставить его работать для «всех» языков может быть очень сложной, если не невозможной задачей.
Øyvind Bråthen
1
Или возьмем польский язык, где форма множественного числа существительного различается в зависимости от числа! : /
UpTheCreek
5

Я считаю, что для того, чтобы иметь возможность иметь множественные сообщения, которые можно будет правильно локализовать, было бы разумно сначала создать уровень косвенного обращения между номером и сообщением.

Например, используйте какую-либо константу, чтобы указать, какое сообщение вы хотите отобразить. Получите сообщение, используя некоторую функцию, которая скроет детали реализации.

get_message(DELETE_WARNING, quantity)

Затем создайте словарь, содержащий возможные сообщения и варианты, и укажите варианты, когда их следует использовать.

DELETE_WARNING = {
   1: 'Are you sure you want to delete %s item',
   >1: 'Are you sure you want to delete %s items'
   >5: 'My language has special plural above five, do you wish to delete it?'
}

Теперь вы можете просто найти ключ, который соответствует, quantityи интерполировать значение quantityс этим сообщением.

Это упрощенный и наивный пример, но я действительно не вижу другого разумного способа сделать это и обеспечить хорошую поддержку L10N и I18N.

Давор Лучич
источник
5

Вам нужно будет перевести приведенную ниже функцию с VBA на C #, но ваше использование изменится на:

int noofitemsselected = SomeFunction();
string message = Pluralize("You have selected # item[s]. Are you sure you want to delete [it/them]?", noofitemsselected);

У меня есть функция VBA, которую я использую в MS Access, чтобы делать именно то, о чем вы говорите. Я знаю, что меня разобьют на куски за публикацию VBA, но все равно здесь. Алгоритм должен быть очевиден из комментариев:

'---------------------------------------------------------------------------------------'
' Procedure : Pluralize'
' Purpose   : Formats an English phrase to make verbs agree in number.'
' Usage     : Msg = "There [is/are] # record[s].  [It/They] consist[s/] of # part[y/ies] each."'
'             Pluralize(Msg, 1) --> "There is 1 record.  It consists of 1 party each."'
'             Pluralize(Msg, 6) --> "There are 6 records.  They consist of 6 parties each."'
'---------------------------------------------------------------------------------------'
''
Function Pluralize(Text As String, Num As Variant, Optional NumToken As String = "#")
Const OpeningBracket = "\["
Const ClosingBracket = "\]"
Const DividingSlash = "/"
Const CharGroup = "([^\]]*)"  'Group of 0 or more characters not equal to closing bracket'
Dim IsPlural As Boolean, Msg As String, Pattern As String

    On Error GoTo Err_Pluralize

    If IsNumeric(Num) Then
        IsPlural = (Num <> 1)
    End If

    Msg = Text

    'Replace the number token with the actual number'
    Msg = Replace(Msg, NumToken, Num)

    'Replace [y/ies] style references'
    Pattern = OpeningBracket & CharGroup & DividingSlash & CharGroup & ClosingBracket
    Msg = RegExReplace(Pattern, Msg, "$" & IIf(IsPlural, 2, 1))

    'Replace [s] style references'
    Pattern = OpeningBracket & CharGroup & ClosingBracket
    Msg = RegExReplace(Pattern, Msg, IIf(IsPlural, "$1", ""))

    'Return the modified message'    
    Pluralize = Msg
End Function

Function RegExReplace(SearchPattern As String, _
                      TextToSearch As String, _
                      ReplacePattern As String) As String
Dim RE As Object

    Set RE = CreateObject("vbscript.regexp")
    With RE
        .MultiLine = False
        .Global = True
        .IgnoreCase = False
        .Pattern = SearchPattern
    End With

    RegExReplace = RE.Replace(TextToSearch, ReplacePattern)
End Function

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

Msg = "There [is/are] # record[s]. [It/They] consist[s/] of # part[y/ies] each."

Pluralize(Msg, 1) --> "There is 1 record.  It consists of 1 party each."
Pluralize(Msg, 6) --> "There are 6 records.  They consist of 6 parties each."

Да, это решение игнорирует языки, кроме английского. Будет ли это иметь значение, зависит от ваших требований.

mwolfe02
источник
4

Вы можете автоматически сгенерировать множественное число, см. Например. множественный генератор .

Правила формирования множественного числа см. В Википедии.

string msg = "Do you want to delete " + numItems + GetPlural(" item", numItems) + "?";
большие пальцы рук
источник
Мне нравится использовать этот метод, если приложение не интернационализировано. Пурализинг приводит к более гладкому нанесению.
cspolton
1
Это действительно сложно интернационализировать, и он часто не работает на английском языке, например: «You have orders + numMice + GetPlural (« mouse », numMice)»
Джеймс Андерсон
@ Джеймс Андерсон: Это не лучший пример с грамматической точки зрения ;-) Не попадитесь в ловушку, думая, что использование метода GetPural - единственный метод, который вам разрешено использовать.
cspolton
в сочетании с еще несколькими функциями для обработки еще нескольких угловых случаев, я думаю, что это очень хорошее решение, хотя и не короче.
lalli
4

Как насчет более общего способа. Избегайте множественного числа во втором предложении:

Количество выбранных элементов для удаления: noofitemsselected.
Ты уверен?

Я обнаружил, что таким образом число ставится в конец строки, что очень легко заметить. Это решение будет работать с той же логикой на любом языке.

Danosaure
источник
«Выбранные элементы для удаления:» звучит неправильно, в предложении указывается список имен, но печатается число. Даже если изменить на «Количество элементов для удаления:», все равно «элементы» будут неудобными.
lalli
@lalli: Да, формулировка не идеальна, и ни одно из предложенных решений не звучит идеально. Я всего лишь предлагаю выразить это в такой форме, как метка и значение. Вы правы насчет добавления Number(я отвечал, пока качал ребенка спать).
Danosaure
4

Мой общий подход - написать "единственную / множественную функцию", например:

public static string noun(int n, string single, string plural)
{
  if (n==1)
    return single;
  else
    return plural;
}

Затем в теле сообщения я вызываю эту функцию:

string message="Congratulations! You have won "+n+" "+noun(n, "foobar", "foobars")+"!";

Это ненамного лучше, но, по крайней мере, он (а) помещает решение в функцию и, таким образом, немного освобождает код, и (б) достаточно гибок, чтобы обрабатывать неправильные множественные числа. т.е. достаточно легко произнести существительное (сущ., «ребенок», «дети») и тому подобное.

Конечно, это работает только для английского языка, но эту концепцию легко распространить на языки с более сложными окончаниями.

Мне пришло в голову, что вы можете сделать последний параметр необязательным для простого случая:

public static string noun(int n, string single, string plural=null)
{
  if (n==1)
    return single;
  else if (plural==null)
    return single+"s";
  else
    return plural;
}
Джей
источник
1
Мне нравится ваша последняя часть, где вы используете значение по умолчанию, чтобы «не загромождать» код в случае операции по умолчанию добавления s для множественного числа существительного.
Øyvind Bråthen
4

Интернационализация

Я предполагаю, что вам нужна поддержка интернационализации, и в этом случае разные языки имеют разные шаблоны для множественного числа (например, специальная форма множественного числа для 2 чего-то или более сложные языки, такие как польский), и вы не можете полагаться на применение какого-то простого шаблона к вашей строке Исправить это.

Вы можете использовать ngettextфункцию GNU Gettext и добавить в исходный код два сообщения на английском языке. Gettext предоставит инфраструктуру для выбора других (потенциально большего количества) сообщений при переводе на другие языки. См. Http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html для полного описания поддержки множественного числа GNU gettext.

GNU Gettext находится под лицензией LGPL. ngettextназван GettextResourceManager.GetPluralStringв порте C # Gettext.

(Если вам не нужна поддержка локализации и вы не хотите сразу использовать Gettext, тогда напишите свою собственную функцию, которая делает это для английского языка, и передайте ей два полных сообщения , таким образом, если вам понадобится l10n позже, вы можете добавить, переписав одну функцию.)

Кен Блум
источник
3

Как насчет написания функции вроде

string GetOutputMessage(int count, string oneItemMsg, string multiItemMsg)
{
 return string.Format("{0} {1}", count, count > 1 ? multiItemMsg : oneItemMsg);
}

.. и использовать его, когда вам нужно?

string message = "You have selected " + GetOutputMessage(noofitemsselected,"item","items") + ". Are you sure you want to delete it/them?";
Павел Морщенюк
источник
3
Вы не думали об этом, не так ли, смех, у вас есть функция для сортировки множителей или нет для предложения, тогда вы идете и ставите «оно / они» в конце лол
Barkermn01
Вы должны просто передать этой функции два сообщения для всего предложения.
Кен Блум,
Это был просто пример. Я понимаю, что более правильный вариант - отправлять целые предложения.
Павел Морщенюк
3

Для первой проблемы, я имею в виду Pluralize, вы можете использовать Inflector .

А для второго вы можете использовать расширение строкового представления с таким именем, как ToPronounString.

Йогеш
источник
3

Вчера один из наших сотрудников задал мне точно такой же вопрос.

Поскольку он снова появился здесь, на StackOverflow, я подумал, что вселенная говорит мне, что я должен попытаться создать достойное решение.

Я быстро собрал что-то воедино, и это ни в коем случае не идеально, но это может быть полезно или вызвать обсуждение / развитие.

Этот код основан на идее, что может быть 3 сообщения. Один для нуля элементов, один для одного элемента и один для более чем одного элемента, которые имеют следующую структуру:

singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural

Я создал внутренний класс для тестирования, чтобы имитировать класс ресурсов. Я еще не тестировал это с использованием фактического файла ресурсов, поэтому мне еще предстоит увидеть полный результат.

Вот код (в настоящее время я включил несколько обобщений, где я знаю, что мог бы указать третий параметр просто как тип, а также второй параметр - это строка, я думаю, что есть способ объединить эти два параметра во что-то лучшее, но я ' Я вернусь к этому, когда у меня будет свободное время.

    public static string GetMessage<T>(int count, string resourceSingularName, T resourceType) where T : Type
{
    var resourcePluralName = resourceSingularName + "_Plural";
    var resourceZeroName = resourceSingularName + "_Zero";
    string resource = string.Empty;
    if(count == 0)
    {
        resource = resourceZeroName;
    }
    else{
        resource = (count <= 1)? resourceSingularName : resourcePluralName;
    }
    var x = resourceType.GetProperty(resource).GetValue(Activator.CreateInstance(resourceType),null);

    return x.ToString();
}

Класс тестового ресурса:

internal class TestMessenger
{
    public string Tester{get{
    return "Hello World of one";}}
    public string Tester_Zero{get{
    return "Hello no world";}}
    public string Tester_Plural{get{
    return "Hello Worlds";}}
}

и мой метод быстрого выполнения

void Main()
{
    var message = GetMessage(56, "Tester",typeof(TestMessenger));
    message.Dump();
}
Джейми Диксон
источник
Если вы хотите, чтобы это было действительно завершено, вам также следует добавить сообщение, singlePropertyName_Allчтобы сделать это еще более очевидным.
Danosaure
2

С моей точки зрения, ваше первое решение является наиболее подходящим. Я говорю, что если вам нужно, чтобы приложение поддерживало несколько языков, второй вариант может оказаться утомительным. При первом подходе текст легко локализовать без особых усилий.

Иллюминаты
источник
2

Вы можете использовать более общее сообщение, например: «Вы действительно хотите удалить выбранные элементы».

Питер
источник
3
Это, безусловно, работает, но я думаю, что идея спрашивающего с первого взгляда показать количество элементов, которые будут удалены, является хорошей. Несколько раз я пытался удалить файл со своего рабочего стола и случайно удалял более одного файла.
Коди Грей
2

Я зависит от того, насколько красивое сообщение вы хотите передать. От простого к сложному:

  1. Перепишите сообщение об ошибке, чтобы избежать множественного числа. Не так приятно для пользователя, но быстрее.

  2. Используйте более общий язык, но все же включайте число (а).

  3. Используйте систему "множественного числа" и инфлекторную систему, как Rails, чтобы вы могли сказать pluralize(5,'bunch')и получить 5 bunches. У Rails есть хороший шаблон для этого.

  4. Для интернационализации вам нужно посмотреть, что предоставляет Java. Это будет поддерживать широкий спектр языков, в том числе те, которые имеют разные формы прилагательных с 2 или 3 элементами. Решение "s" очень ориентировано на английский язык.

Какой вариант вы выберете, зависит от целей вашего продукта. - ндп

ндп
источник
2

Почему вы хотите представить сообщение, которое действительно могут понять пользователи? Это идет вразрез с 40-летней историей программирования. Нееееет, у нас хорошие дела, не портите их понятными сообщениями.


(Дж / К)

Джон Алексиу
источник
+1: приятно видеть здесь немного юмора. Но даже если вы шутите, я понимаю вашу основную мысль. Многие программы, созданные за эти годы, имеют очень плохие сообщения. Обычно потому, что они в любом случае получают техническую информацию, которую может понять обычный пользователь.
Øyvind Bråthen
Хорошая точка зрения. Мне всегда нравится, когда я получаю сообщение типа «Ошибка 494-B при вводе данных пользователем» - оно добавляет дополнительную тайну о том, что именно не так, что делает жизнь намного интереснее. Недавно я получил ошибку при попытке создать пароль, в котором просто говорилось: «Пароль не соответствует требованиям безопасности». Никаких намеков на то, какое требование я не выполнял. Мой пароль состоял из заглавных и строчных букв и нескольких цифр. Я пробовал добавить светского персонажа. Все еще нет. Наконец, это прошло, когда я УДАЛЕНИЕ персонажа. Я думаю, у них было правило, что нельзя использовать один и тот же персонаж дважды подряд.
Джей
2

Сделайте так, как это сделано в World of Warcraft:

BILLING_NAG_WARNING = "Your play time expires in %d |4minute:minutes;";
Томас Бонини
источник
0

Он становится немного короче с

string message = "Are you sure you want to delete " + noofitemsselected + " item" + (noofitemsselected>1 ? "s" : "") + "?";
Йонас Эльфстрём
источник
0

Один из подходов, о котором я не упоминал, - это использование тега замены / выбора (например, что-то вроде «Вы собираетесь раздавить {0} [? I ({0} = 1): / cactus / cacti /]». (другими словами, укажите в выражении, подобном формату, замену на основе того, равен ли нулевой аргумент, взятый как целое число, 1). Я видел такие теги, использованные в дни до .net; я не знаю ни одного стандарт для них в .net, и я не знаю лучшего способа их отформатировать.

суперкар
источник
0

Я бы подумал на минуту прямо из коробки, все предложения здесь либо включают множественное число (и беспокоятся о более чем 1 уровне множественного числа, пола и т. Д.), Либо не используют его вообще и обеспечивают хорошую отмену.

Я бы пошел неязычным путем и использовал для этого визуальные очереди. Например, представьте, что в приложении для Iphone вы выбираете элементы, вытирая палец. перед удалением их с помощью основной кнопки удаления, он «встряхнет» выбранные элементы и покажет вам вопросительный знак с заголовком с кнопками V (ок) или X (отмена) ...

Или, в трехмерном мире Kinekt / Move / Wii - представьте, что вы выбираете файлы, перемещаете руку к кнопке удаления и вам приказывают поднять руку над головой для подтверждения (используя те же визуальные символы, что я упоминал ранее. Например, вместо попросить вас удалить 3 файла? он покажет вам 3 файла с парящим полупрозрачным красным X и скажет вам сделать что-то для подтверждения.

Эран Медан
источник