Pluralidade nas mensagens do usuário

106

Muitas vezes, ao gerar mensagens para mostrar ao usuário, a mensagem conterá uma série de algo que desejo informar ao cliente.

Vou dar um exemplo: o cliente selecionou uma série de itens de 1 em diante e clicou em excluir. Agora, quero deixar uma mensagem de confirmação para o cliente e mencionar o número de itens que ele selecionou para minimizar a chance de ele cometer um erro ao selecionar um monte de itens e clicar em excluir quando ele só deseja excluir um dos eles.

Uma maneira é fazer a mensagem genérica assim:

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

O "problema" aqui é o caso em que noofitemselectedé 1, e temos que escrever item e ele em vez de itens e eles .

Minha solução normal será algo assim

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

Isso fica muito longo e muito desagradável muito rápido se houver muitas referências à pluralidade de números dentro do código, e a mensagem real ficar difícil de ler.

Portanto, minhas perguntas são simples. Existe alguma maneira melhor de gerar mensagens como esta?

EDITAR

Vejo que muitas pessoas ficaram muito presas no caso de eu ter mencionado que a mensagem deveria ser exibida dentro de uma caixa de mensagem e simplesmente deu uma resposta de como evitar o uso da caixa de mensagem, e isso é bom .

Mas lembre-se de que o problema de pluralização também se aplica a textos em outros lugares do programa além de caixas de mensagens. Por exemplo, um rótulo ao lado de uma grade exibindo o número de linhas selecionadas na grade terá o mesmo problema em relação à pluralização.

Portanto, isso se aplica basicamente à maioria do texto que é gerado de alguma forma a partir de programas, e então a solução não é tão simples quanto apenas mudar o programa para não produzir mais texto :)

Øyvind Bråthen
fonte
6
@ 0xA3: Eu realmente não sei se cada idioma tem uma pluralização que é facilmente expressa como "item (ns)".
Jens
5
Você provavelmente também deveria estar pensando em localização. Esse problema pode ficar muito pior.
Alex Brown
4
@Jens: Geralmente não, da maneira menos conveniente possível. Algumas línguas têm, por exemplo, pluralizações diferentes para 2-4 e para 5-infinito, tudo isso dependendo do gênero. "Línguas naturais: loucura de localização! Em breve em um computador perto de você!"
Piskvor saiu do prédio em
29
IMO, nada faz os programadores parecerem mais preguiçosos para os usuários do que a má pluralidade.
Greg
4
@ Øyvind: +1 para sua edição. Parece que muitos dos "respondentes" aqui estão mais empenhados em provar que sua pergunta está errada, em vez de oferecer uma solução certa. Anti-soluções, se preferir.
mwolfe02

Respostas:

53

Se houver alguma chance, por menor que seja, de que este aplicativo precise ser traduzido para outros idiomas, ambos estão errados. A maneira correta de fazer isso é:

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

Isso ocorre porque idiomas diferentes lidam com a pluralidade de maneiras diferentes. Alguns, como o malaio, nem mesmo têm plurais sintáticos, então as cordas geralmente são idênticas. Separar as duas strings torna mais fácil oferecer suporte a outros idiomas posteriormente.

Caso contrário, se este aplicativo se destina a ser consumido pelo público em geral e deve ser amigável, o segundo método é preferível. Desculpe, mas eu realmente não conheço uma maneira mais curta de fazer isso.

Se este aplicativo se destina a ser consumido apenas internamente pela sua empresa, faça o atalho "item(s)". Você realmente não precisa impressionar ninguém ao escrever um código empreendedor. Mas eu desaconselho fazer isso para aplicativos de consumo público, porque isso dá a impressão de que o programador é preguiçoso e, portanto, rebaixa sua opinião sobre a qualidade do aplicativo. Confie em mim, pequenas coisas como esta importam.

slebetman
fonte
35
Embora eu concorde com a premissa, Você está ignorando idiomas que têm mais de dois graus de pluralidade. (Pegue o russo, por exemplo. Três maneiras diferentes de dizer, dependendo se é 1, <5 ou> = 5 e mesmo isso depende do que exatamente você está falando). Basicamente, estou dizendo que você precisa de uma instrução condicional mais forte e não apenas de um operador ternário.
crítico de
4
Você pode até mesmo otimizar o noofitemsselectedneste exemplo para a primeira opção; já que você sabe que é 1.
Padrão
16
Já que falamos nisso, o hebraico pode ter diferentes pluralidades para 1, 2, 3-10 e 11+.
Joel Spolsky
3
@Joel, o hebraico pode ter tantas pluralidades diferentes? לא ידעתי (eu não sabia)! O hebraico moderno é como o inglês no que diz respeito aos plurais (embora o hebraico antigo também tivesse uma forma dual.)
Ken Bloom
3
Em inglês, zero é tratado como um plural (0 itens, 2 itens); o que acontece com zero em hebraico, russo, romeno? Existe uma maneira simples de identificar os intervalos? Estou supondo que as informações devem ser determinadas por idioma, portanto, qualquer sistema baseado em arquivos de mensagem tem que lidar com quantidades variáveis ​​de pluralidade em um conjunto de mensagens. Ai! Configurar as traduções também seria complicado - diferentes números de mensagens são necessários para diferentes idiomas.
Jonathan Leffler
94

Você pode evitar toda essa pluralidade confusa apenas excluindo os itens sem nenhuma mensagem e dando ao usuário um recurso de Desfazer muito bom. Os usuários nunca lêem nada . Você deve construir uma boa instalação de Desfazer como parte de seu programa de qualquer maneira.

Na verdade, você obtém 2 benefícios ao criar uma facilidade Undo abrangente. O primeiro benefício facilita a vida do usuário ao permitir que ele reverta erros e minimize a leitura. O segundo benefício é que seu aplicativo reflete a vida real, permitindo a reversão do fluxo de trabalho não trivial (não apenas erros).

Certa vez, escrevi um aplicativo sem usar uma única caixa de diálogo ou mensagem de confirmação. Demorou muito e foi significativamente mais difícil de implementar do que usar mensagens do tipo confirmação. Mas o resultado final foi bastante bom de usar de acordo com seus usuários finais.

HTTP 410
fonte
12
Por alguma razão, eu realmente sinto que concordo com isso e deveria votar positivamente.
Cody Gray
4
@ Øyvind, Eis o porquê: Mensagens solicitando verificação ao usuário são caras para o usuário, especialmente quando são apresentadas na forma de uma caixa de diálogo modal que interrompe tudo até que o usuário responda a caixa de diálogo. Isso irrita muitos usuários, a ponto de eles começarem a clicar em qualquer botão para passar da caixa de diálogo (em quantos instaladores você acabou de clicar em próximo, próximo, próximo? ). Consequentemente, é mais seguro e há muito menos atrito com o usuário se você apenas fizer uma exclusão suave e fornecer um recurso de desfazer. O Gmail usa essa técnica com grande eficácia.
Robert Harvey
5
Debatível, mas em qualquer caso, o mesmo problema aparecerá em casos diferentes de uma mensagem de confirmação em uma exclusão, portanto, esta resposta é realmente tangencial à pergunta.
Jay
50
eu votei positivamente sem ler. sempre posso desfazê-lo mais tarde
Steven A. Lowe
6
@Robert Harvey: Provavelmente apócrifo, mas muitos anos atrás eu li que a Lotus enviou 40.000 unidades do Lotus Notes para o Mac e 60.000 foram devolvidas. A interface era tão ruim que até mesmo as pessoas que haviam pirateado a enviaram de volta.
Duncan
39

Que tal apenas:

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

Dessa forma, você elimina as dificuldades de acordo de número e acaba com uma mensagem de erro ainda mais curta e mais direta para o usuário como um bônus. Todos nós sabemos que os usuários não leem mensagens de erro de qualquer maneira . Quanto mais curtos forem, maior será a probabilidade de, pelo menos, dar uma olhada no texto.

Ou, sabendo que os usuários não lêem mensagens de erro, você poderia abordar isso de uma maneira diferente. Ignore completamente a mensagem de confirmação e forneça apenas um recurso de desfazer que simplesmente funciona, independentemente do que foi excluído. A maioria dos usuários já está acostumada a desfazer uma operação quando percebe que ela não é o que desejam, e provavelmente achará esse comportamento mais natural do que ter que lidar com outro pop-up irritante.

Cody Gray
fonte
1
Boa resposta. No entanto, foi solicitado pelo cliente, neste caso, o fornecimento de mensagens de erro para muitos casos, porque ele sentiu que era a melhor abordagem. Mas mudar o texto pode pelo menos minimizar o problema e torná-lo menos confuso.
Øyvind Bråthen
@ Øyvind: Muito justo. Já que você tem que seguir o cliente, eu escolheria a primeira abordagem que propus ou usaria um arquivo de Recursos com uma função de manipulador. Só achei que valia a pena apontar uma alternativa porque é facilmente esquecida. Caramba, eu nem pensei nisso até depois de enviar minha primeira resposta.
Cody Gray
As alternativas são bem-vindas. É por isso que também dei +1 :)
Øyvind Bråthen
1
+1 por não tentar resolver um problema insolúvel. E lembre-se da lei de Steve Krug: remova metade das palavras. Então faça de novo. Eu uso: "Excluir {x} item (ns)?"
Serge Wautier,
20

E o que Java teve por anos: java.text.MessageFormat e ChoiceFormat? Consulte http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html para obter mais informações.

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.

No seu caso, você quer algo um pouco mais simples:

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

A vantagem dessa abordagem é que ela funciona bem com os pacotes i18n e você pode fornecer traduções adequadamente para idiomas (como o japonês) que não têm conceito de palavras no plural ou no singular.

Berin Loritsch
fonte
1
Essa abordagem funciona bem para lidar com a pluralidade, mas não lida com gênero, infelizmente. Você precisa de uma string diferente para cada tipo de coisa que pode ser excluída.
Sr. Brilhante e Novo 安 宇
Se você conhece o substantivo, pode moldar as frases para trabalhar com o adjetivo adequado. Mas sim, tendo estudado grego clássico, você tem uma forma diferente da palavra baseada em substantivos masculinos, femininos ou neutros (o adjetivo assume a forma do substantivo que modifica), e a forma difere com base em sua função na frase ( sujeito, objeto, etc.). Sempre podemos encontrar casos em que uma solução funciona e outra não. Esta é a maneira como o pessoal de Java tentou resolver o problema. Você ainda precisa ter cuidado com a forma como forma os formatos de mensagem.
Berin Loritsch
Você sempre pode alimentar a solução Java com dois inteiros, onde o segundo indica o gênero. (Mas, na realidade, a concordância de gênero geralmente é menos preocupante simplesmente porque o caso de uso de ajustar diferentes objetos em uma mensagem é menos frequente do que ajustar diferentes números do mesmo objeto em uma mensagem)
Ken Bloom
12

Eu não iria codificar a mensagem, mas fornecer duas mensagens em um arquivo de recurso separado. Gostar

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?";

e, em seguida, alimentando-os em String.Format como

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

string message = String.Format(messageTemplate, noofitemsselected)

Acho que essa abordagem é mais fácil de localizar e manter. Todas as mensagens da IU estariam em um único local.

Jens
fonte
1, eu gosto dessa abordagem. Embora, você precise manter o controle dos equivalentes de nomes de recursos.
Padrão de
11

Você pode contornar o problema completamente formulando a mensagem de maneira diferente.

string message = "The number of selected items is " + noofitemsselected + ". Are you sure you want to delete everything in this selection?";
gdejohn
fonte
10

A primeira coisa que sugiro é: use string.Format. Isso permite que você faça algo assim:

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

Além disso, em aplicativos WPF, eu vi sistemas em que uma string de recurso seria delimitada por barras verticais para ter duas mensagens: uma mensagem singular e uma mensagem plural (ou até mesmo uma mensagem zero / única / muitos). Um conversor personalizado pode ser usado para analisar esse recurso e usar a string relevante (formatada), de modo que seu Xaml seja algo assim:

<TextBlock Text="{Binding numOfItems, Converter={StaticResource c:NumericMessageFormatter}, ConverterParameter={StaticResource s:SuitableMessageTemplate}}" />
Dan Puzey
fonte
7

Para inglês, muitas respostas acima. Para outras línguas, é mais difícil, pois os plurais dependem do gênero do substantivo e da terminação da palavra. Alguns exemplos em francês:

Masculino normal:

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

Feminino regular

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

Irregular masculino (termina com 's')

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

O mesmo problema existe na maioria das línguas latinas e se agrava no alemão ou no russo, onde há 3 gêneros (maculino, feminino e neutro).

Você precisa ter cuidado se seu objetivo é lidar com mais do que apenas inglês.

homem sorridente
fonte
Pelo menos no meu caso, isso não é realmente um problema. Para cada texto que desejo inserir o número, saberei qual é o substantivo ao gerar a string. Mas para fazer uma solução mais geral, eu concordo com você, que fazer isso funcionar para "todos" os idiomas pode ser uma tarefa muito difícil, senão impossível.
Øyvind Bråthen
1
Ou tome o polonês, onde a forma plural do substantivo usado é diferente dependendo do número! : /
UpTheCreek
5

Para poder ter mensagens pluralizadas que serão possíveis de localizar corretamente, minha opinião é que seria sensato primeiro criar uma camada de indireção entre o número e uma mensagem.

Por exemplo, use uma constante de algum tipo para especificar qual mensagem você deseja exibir. Busque a mensagem usando alguma função que irá ocultar os detalhes de implementação.

get_message(DELETE_WARNING, quantity)

Em seguida, crie um dicionário que contenha as mensagens e variações possíveis e faça com que as variações saibam quando devem ser usadas.

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?'
}

Agora você pode simplesmente encontrar a chave que corresponde a quantitye interpolar o valor de quantitycom essa mensagem.

Este exemplo simplificado e ingênuo, mas eu realmente não vejo nenhuma outra maneira sã de fazer isso e ser capaz de fornecer um bom suporte para L10N e I18N.

Davor Lucic
fonte
5

Você terá que traduzir a função abaixo de VBA para C #, mas seu uso mudaria para:

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

Eu tenho uma função VBA que uso no MS Access para fazer exatamente o que você está falando. Eu sei que serei cortado em pedaços por postar no VBA, mas lá vai de qualquer maneira. O algoritmo deve ser aparente a partir dos comentários:

'---------------------------------------------------------------------------------------'
' 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

O uso foi cortado um pouco nos comentários de código acima, então vou repetir aqui:

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

Sim, esta solução ignora idiomas que não sejam o inglês. Se isso importa depende dos seus requisitos.

mwolfe02
fonte
4

Você pode gerar o plural automaticamente, consulte, por exemplo. gerador plural .

Para regras de geração de plural, consulte a wikipedia

string msg = "Do you want to delete " + numItems + GetPlural(" item", numItems) + "?";
thumbmunkeys
fonte
Gosto de usar esse método se o aplicativo não for internacionalizado. Puralising resulta em uma aplicação mais polida.
cspolton
1
É realmente difícil internacionalizar isso, e muitas vezes falha em inglês, por exemplo, "Você tem pedidos + numMice + GetPlural (" mouse ", numMice)"
James Anderson
@James Anderson: Esse não é o melhor exemplo gramatical, é ;-) Não caia na armadilha de pensar que usar um método GetPural é o único método que você tem permissão para usar.
cspolton
juntamente com mais algumas funções para lidar com mais alguns casos esquivos, acho que esta é uma solução muito boa, embora não mais curta.
lalli
4

Que tal uma forma mais genérica. Evite a pluralização na segunda frase:

Número de itens selecionados a serem excluídos: noofitemsselected.
Você tem certeza?

Descobri que fazer dessa forma coloca o número no final da linha, o que é realmente fácil de detectar. Essa solução funcionaria com a mesma lógica em qualquer idioma.

Danosaure
fonte
"Itens selecionados a serem excluídos:" não parece certo, a frase indica uma lista de nomes, mas um número é impresso. Mesmo se alterado para "Número de itens a serem excluídos:", ainda assim "itens" é estranho.
lalli
@lalli: Sim, o texto não é perfeito e nenhuma das soluções fornecidas parece perfeita. Estou apenas sugerindo colocá-lo em uma forma como rótulo e valor. Você está certo sobre adicionar Number(eu estava respondendo enquanto embalava meu bebê para dormir).
Danosaure
4

Minha abordagem geral é escrever uma "função única / plural", como esta:

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

Então, no corpo da mensagem, chamo esta função:

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

Isso não é muito melhor, mas pelo menos, (a) coloca a decisão em uma função e, portanto, organiza um pouco o código, e (b) é flexível o suficiente para lidar com plurais irregulares. ou seja, é fácil dizer o substantivo (n, "filho", "filhos") e assim por diante.

É claro que isso só funciona para o inglês, mas o conceito é facilmente extensível para idiomas com terminações mais complexas.

Ocorreu-me que você poderia tornar o último parâmetro opcional para o caso fácil:

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;
}
Jay
fonte
1
Eu gosto da sua última parte, onde você usa um valor padrão para "organizar" o código no caso da operação padrão de adicionar um s para pluralizar o substantivo.
Øyvind Bråthen
4

Internacionalização

Presumo que você queira suporte de internacionalização, caso em que diferentes idiomas têm padrões diferentes para plurais (por exemplo, uma forma especial de plural para 2 de alguma coisa, ou idiomas mais complicados como o polonês), e você não pode confiar na aplicação de algum padrão simples à sua string para fixar isso.

Você pode usar a ngettextfunção GNU Gettext e fornecer duas mensagens em inglês em seu código-fonte. Gettext fornecerá a infraestrutura para escolher entre outras (potencialmente mais) mensagens quando traduzidas para outros idiomas. Veja http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html para uma descrição completa do suporte plural do GNU gettext.

GNU Gettext está sob a LGPL. ngettexté nomeado GettextResourceManager.GetPluralStringna porta C # de Gettext.

(Se você não precisa de suporte de localização e não quer usar o Gettext imediatamente, escreva sua própria função que faz isso para o inglês e passe duas mensagens completas para ela; dessa forma, se precisar de l10n mais tarde, você pode adicione reescrevendo uma única função.)

Ken Bloom
fonte
3

Que tal escrever uma função como

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

.. e usá-lo sempre que precisar?

string message = "You have selected " + GetOutputMessage(noofitemsselected,"item","items") + ". Are you sure you want to delete it/them?";
Pavel Morshenyuk
fonte
3
você não pensou nisso, hehe lol, você tem uma função para ordenar multiplica ou não para a frase então você vai e coloca "it / them" no final rs
Barkermn01
Você deve apenas passar duas mensagens para a frase inteira para esta função.
Ken Bloom
Foi só um exemplo. Sei que a variante de enviar frases inteiras é mais correta.
Pavel Morshenyuk
3

Para o primeiro problema, quero dizer Pluralize, você pode usar o Inflector .

E para o segundo, você pode usar uma extensão de representação de string com um nome como ToPronounString.

Yogesh
fonte
3

Eu tive exatamente a mesma pergunta feita a mim ontem por um membro de nossa equipe.

Desde que surgiu novamente aqui no StackOverflow, imaginei que o universo estava me dizendo para ter uma batalha na produção de uma solução decente.

Eu rapidamente montei algo e não é de forma perfeita, mas pode ser útil ou gerar alguma discussão / desenvolvimento.

Este código é baseado na ideia de que pode haver 3 mensagens. Um para zero itens, um para um item e um para mais de um item que seguem a seguinte estrutura:

singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural

Eu criei uma classe interna para testar a fim de imitar a classe de recursos. Eu não testei isso usando um arquivo de recurso real ainda, então ainda estou para ver o resultado completo.

Aqui está o código (atualmente, incluí alguns genéricos onde sei que poderia ter especificado o terceiro parâmetro simplesmente como um tipo e também o segundo parâmetro é uma string, acho que há uma maneira de combinar esses dois parâmetros em algo melhor, mas eu ' Voltarei a isso quando tiver um momento livre.

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

Classe de recurso de teste:

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";}}
}

e meu método de execução rápida

void Main()
{
    var message = GetMessage(56, "Tester",typeof(TestMessenger));
    message.Dump();
}
Jamie Dixon
fonte
Se você quiser que isso seja realmente completo, você também deve adicionar uma mensagem para singlePropertyName_Alltorná-lo ainda mais óbvio.
Danosaure
2

Do meu ponto de vista, sua primeira solução é a mais adequada. O que digo é que, no caso de você precisar que o aplicativo suporte vários idiomas, a segunda opção pode ser trabalhosa. Com a primeira abordagem, é fácil localizar o texto sem muito esforço.

Illuminati
fonte
2

Você poderia ir para uma mensagem mais genérica como 'Tem certeza de que deseja excluir o (s) item (ns) selecionado (s)'.

Peter
fonte
3
Isso certamente funciona, mas acho que a ideia do autor da pergunta de mostrar o número de itens prestes a serem excluídos é boa. Mais de uma vez, tentei excluir um arquivo da minha área de trabalho e, acidentalmente, excluí mais de um arquivo.
Cody Gray
2

Depende de quão boa é a mensagem que você deseja ter. Do mais fácil ao mais difícil:

  1. Reescreva sua mensagem de erro para evitar pluralização. Não é tão bom para o seu usuário, mas mais rápido.

  2. Use uma linguagem mais geral, mas ainda inclua o (s) número (s).

  3. Use um sistema de "pluralização" e infletor ala Rails, para que você possa dizer pluralize(5,'bunch')e obter 5 bunches. Rails tem um bom padrão para isso.

  4. Para internacionalização, você precisa olhar o que Java oferece. Isso suportará uma grande variedade de idiomas, incluindo aqueles que têm diferentes formas de adjetivos com 2 ou 3 itens. A solução "s" é muito centrada em inglês.

A opção escolhida depende de seus objetivos de produto. - ndp

ndp
fonte
2

Por que você deseja apresentar uma mensagem que os usuários possam realmente entender? Vai contra 40 anos de história de programação. Nããão, temos uma coisa boa acontecendo, não a estrague com mensagens compreensíveis .


(j / k)

John alexiou
fonte
+1: bom ver um pouco de humor aqui também. Mas mesmo que você esteja brincando, eu entendo seu ponto subjacente. Muitos programas criados durante os anos contêm mensagens extremamente ruins. Normalmente porque eles chegam a ser muito técnicos para um usuário normal entender.
Øyvind Bråthen
Bom ponto. Sempre adoro quando recebo uma mensagem como "Erro 494-B na entrada do usuário" - adiciona aquele pequeno mistério extra sobre o que está errado que torna a vida muito mais interessante. Recentemente, recebi um erro ao tentar criar uma senha que dizia simplesmente: "A senha não atende aos requisitos de segurança". Nenhuma dica de qual requisito eu não estava atendendo. Minha senha incluía letras maiúsculas e minúsculas e vários dígitos. Tentei adicionar um personagem secial. Ainda não. Finalmente passou quando eu DELETEI um personagem. Acho que eles tinham uma regra de que você não pode ter o mesmo personagem duas vezes seguidas.
Jay
2

Faça como no World of Warcraft:

BILLING_NAG_WARNING = "Your play time expires in %d |4minute:minutes;";
Thomas Bonini
fonte
0

Ele fica um pouco mais curto com

string message = "Are you sure you want to delete " + noofitemsselected + " item" + (noofitemsselected>1 ? "s" : "") + "?";
Jonas Elfström
fonte
0

Uma abordagem que não vi mencionada seria o uso de uma substituição / tag de seleção (por exemplo, algo como "Você está prestes a esmagar {0} [? I ({0} = 1): / cactus / cacti /]". (em outras palavras, tenha uma expressão semelhante a um formato que especifique a substituição com base em se o argumento zero, considerado como um inteiro, é igual a 1). Eu vi essas tags usadas antes de .net; não estou ciente de nenhuma padrão para eles em .net, nem sei a melhor maneira de formatá-los.

supergato
fonte
0

Eu pensaria fora da caixa por um minuto, todas as sugestões aqui são: fazer a pluralização (e se preocupar com mais de 1 nível de pluralização, gênero, etc.) ou não usá-la de forma alguma e fornecer um bom desfazer.

Eu seguiria o caminho não lingual e usaria filas visuais para isso. por exemplo, imagine um aplicativo para iPhone em que você seleciona itens limpando o dedo. antes de excluí-los usando o botão mestre de exclusão, ele "sacudirá" os itens selecionados e mostrará uma caixa de ponto de interrogação intitulada com botões V (ok) ou X (cancelar) ...

Ou, no mundo 3D de Kinekt / Move / Wii - imagine selecionar os arquivos, mover sua mão para o botão delete e ser instruído a mover sua mão acima da cabeça para confirmar (usando os mesmos símbolos visuais que mencionei antes. Por exemplo, de pedir para você deletar 3 arquivos? ele irá mostrar a você 3 arquivos com um X vermelho meio transparente pairando sobre e dizer para você fazer algo para confirmar.

Eran Medan
fonte