Pluralidad en los mensajes de los usuarios

106

Muchas veces, al generar mensajes para mostrar al usuario, el mensaje contendrá una serie de algo sobre lo que quiero informar al cliente.

Daré un ejemplo: el cliente ha seleccionado varios elementos del 1 en adelante y ha hecho clic en eliminar. Ahora quiero enviar un mensaje de confirmación al cliente, y quiero mencionar la cantidad de elementos que ha seleccionado para minimizar la posibilidad de que cometa un error al seleccionar un montón de elementos y hacer clic en eliminar cuando solo quiere eliminar uno de ellos.

Una forma es hacer que el mensaje genérico sea así:

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

El "problema" aquí es el caso donde noofitemselectedes 1, y tenemos que escribir item y él en lugar de items y ellos .

Mi solución normal será algo como esto

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

Esto se vuelve bastante largo y bastante desagradable muy rápido si hay muchas referencias a la pluralidad de números dentro del código, y el mensaje real se vuelve difícil de leer.

Entonces mi pregunta es simple. ¿Existen mejores formas de generar mensajes como este?

EDITAR

Veo que muchas personas se han quedado muy colgadas en el caso de que mencioné que el mensaje debería mostrarse dentro de un cuadro de mensaje, y simplemente dio una respuesta de cómo evitar usar el cuadro de mensaje, y eso está muy bien. .

Pero recuerde que el problema de la pluralización también se aplica a textos en otros lugares del programa además de los cuadros de mensajes. Por ejemplo, una etiqueta junto a una cuadrícula que muestre el número de líneas seleccionadas en la cuadrícula tendrá el mismo problema con respecto a la pluralización.

Entonces, esto básicamente se aplica a la mayoría del texto que se genera de alguna manera desde los programas, y luego la solución no es tan simple como simplemente cambiar el programa para que ya no genere texto :)

Øyvind Bråthen
fuente
6
@ 0xA3: Realmente no sé si cada idioma tiene una pluralización que se expresa tan fácilmente como "elemento (s)".
Jens
5
Probablemente también debería pensar en la localización. Este problema puede empeorar mucho.
Alex Brown
4
@Jens: Por lo general, no lo hacen, de la manera menos conveniente posible. Algunos idiomas tienen, por ejemplo, diferentes pluralizaciones para 2-4 que para 5-infinito, todo eso dependiendo del género. "Lenguas naturales: ¡Locura por la localización! ¡Próximamente en una computadora cercana!"
Piskvor salió del edificio el
29
En mi opinión, nada hace que los programadores parezcan más vagos para los usuarios que la mala pluralidad.
Greg
4
@ Øyvind: +1 para su edición. Parece que muchos de los "respondedores" aquí están más decididos a demostrar que su pregunta es incorrecta, en lugar de ofrecer una solución correcta. Anti-soluciones, por así decirlo.
mwolfe02

Respuestas:

53

Si alguna vez existe la posibilidad, por pequeña que sea, de que esta aplicación deba traducirse a otros idiomas, ambos están equivocados. La forma correcta de hacer esto es:

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

Esto se debe a que los diferentes idiomas manejan la pluralidad de manera diferente. Algunos, como el malayo, ni siquiera tienen plurales sintácticos, por lo que las cadenas suelen ser idénticas. La separación de las dos cadenas facilita la compatibilidad con otros idiomas más adelante.

De lo contrario, si esta aplicación está destinada a ser consumida por el público en general y se supone que es fácil de usar, entonces es preferible el segundo método. Lo siento, pero realmente no conozco una forma más corta de hacer esto.

Si esta aplicación está destinada a ser consumida solo internamente por su empresa, haga el atajo "item(s)". Realmente no tiene que impresionar a nadie al escribir código enterprisy. Pero desaconsejaría hacer esto para aplicaciones de consumo público porque da la impresión de que el programador es vago y, por lo tanto, reduce su opinión sobre la calidad de la aplicación. Créame, pequeñas cosas como esta importan.

slebetman
fuente
35
Si bien estoy de acuerdo con la premisa, estás ignorando los idiomas que tienen más de dos grados de pluralidad. (Tome el ruso, por ejemplo. Tres formas diferentes de decir dependiendo de si es 1, <5 o> = 5 e incluso eso depende de qué está hablando exactamente). Básicamente, estoy diciendo que necesita una declaración condicional más fuerte y no solo un operador ternario.
crasic
4
Incluso puede optimizar noofitemsselecteden este ejemplo para la primera opción; ya que sabe que es 1.
Predeterminado el
16
Mientras estamos en eso, el hebreo puede tener diferentes pluralidades para 1, 2, 3-10 y 11+.
Joel Spolsky
3
@Joel, ¿el hebreo puede tener tantas pluralidades diferentes? לא ידעתי (no lo sabía)! El hebreo moderno es como el inglés en lo que respecta a los plurales (aunque el hebreo antiguo también tenía una forma dual)
Ken Bloom
3
En inglés, cero se trata como un plural (0 elementos, 2 elementos); ¿Qué pasa con el cero en hebreo, ruso, rumano? ¿Existe una forma sencilla de identificar los rangos? Supongo que la información debe determinarse por idioma, por lo que cualquier sistema basado en archivos de mensajes debe lidiar con cantidades variables de pluralidad en un conjunto de mensajes. ¡Ay! Configurar las traducciones también sería complicado: se necesitan diferentes números de mensajes para diferentes idiomas.
Jonathan Leffler
94

Puede evitar toda esta pluralidad desordenada simplemente eliminando los elementos sin ningún mensaje y brindando al usuario una función Deshacer realmente buena. Los usuarios nunca leen nada . De todos modos, debería crear una buena función Deshacer como parte de su programa.

De hecho, obtiene 2 beneficios cuando crea una función completa de Deshacer. El primer beneficio facilita la vida del usuario al permitirle revertir los errores y minimizar la lectura. El segundo beneficio es que su aplicación refleja la vida real al permitir la reversión del flujo de trabajo no trivial (no solo errores).

Una vez escribí una aplicación sin usar un solo diálogo o mensaje de confirmación. Tomó un pensamiento serio y fue significativamente más difícil de implementar que usar mensajes de tipo confirmación. Pero el resultado final fue bastante agradable de usar según sus usuarios finales.

HTTP 410
fuente
12
Por alguna razón, realmente siento que estoy de acuerdo con esto y debería votarlo.
Cody Gray
4
@ Øyvind, He aquí por qué: Los mensajes que piden verificación al usuario son costosos para el usuario, especialmente cuando se presentan en forma de un cuadro de diálogo modal que detiene todo hasta que el usuario responde al diálogo. Esto molesta a muchos usuarios, hasta el punto en que comienzan a hacer clic en cualquier botón para pasar del cuadro de diálogo (¿cuántos instaladores acaba de hacer clic en siguiente, siguiente, siguiente? ). En consecuencia, es más seguro y hay mucha menos fricción para el usuario, si solo realiza una eliminación suave y proporciona una capacidad de deshacer. Gmail utiliza esta técnica con gran eficacia.
Robert Harvey
5
Es discutible, pero en cualquier caso, el mismo problema surgirá en otros casos que no sean un mensaje de confirmación en una eliminación, por lo que esta respuesta es realmente tangencial a la pregunta.
Jay
50
voté a favor de esto sin leerlo. Siempre puedo deshacerlo más tarde
Steven A. Lowe
6
@Robert Harvey: Probablemente apócrifo, pero hace muchos años leí que Lotus había enviado 40.000 unidades de Lotus Notes para Mac y se devolvieron 60.000. La interfaz era tan mala que incluso las personas que la habían pirateado la enviaron de vuelta.
Duncan
39

¿Qué tal solo:

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

De esa manera, elimina las dificultades del acuerdo numérico y termina con un mensaje de error aún más corto y más directo para el usuario como beneficio adicional. Todos sabemos que los usuarios no leen los mensajes de error de todos modos . Cuanto más cortos sean, más probable es que al menos echen un vistazo al texto.

O, armado con este conocimiento de que los usuarios no leen los mensajes de error, podría abordar esto de una manera diferente. Omita el mensaje de confirmación por completo y solo proporcione una función de deshacer que Just Works, independientemente de lo que se eliminó. La mayoría de los usuarios ya están acostumbrados a deshacer una operación cuando se dan cuenta de que no era lo que querían y es probable que encuentren este comportamiento más natural que tener que lidiar con otra ventana emergente molesta.

Cody Grey
fuente
1
Buena respuesta. Sin embargo, en este caso, el cliente solicitó que se proporcionaran mensajes de error en muchos casos porque consideró que era el mejor enfoque. Pero cambiar el texto puede al menos minimizar el problema y hacer que sea menos complicado.
Øyvind Bråthen
@ Øyvind: Bastante justo. Dado que tiene que seguir al cliente, tomaría el primer enfoque que propuse o usaría un archivo de recursos con una función de controlador. Pensé que valía la pena señalar una alternativa porque se olvida fácilmente. Diablos, ni siquiera pensé en eso hasta después de que envié mi primera respuesta.
Cody Gray
Las alternativas son bienvenidas. Por eso también le di un +1 :)
Øyvind Bråthen
1
+1 por no intentar resolver un problema irresoluble. Y recuerde la ley de Steve Krug: elimine la mitad de las palabras. Entonces hazlo de nuevo. Yo uso: "¿Eliminar {x} artículo (s)?"
Serge Wautier
20

¿Qué pasa con lo que Java ha tenido durante años: java.text.MessageFormat y ChoiceFormat? Consulte http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html para obtener más información.

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.

En tu caso quieres algo algo más sencillo:

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

La ventaja de este enfoque es que funciona bien con los paquetes i18n y puede proporcionar traducciones correctamente para idiomas (como el japonés) que no tienen concepto de palabras en plural o singular.

Berin Loritsch
fuente
1
Este enfoque funciona bien para manejar la pluralidad, pero lamentablemente no maneja el género. Necesita una cadena diferente para cada tipo de elemento que se pueda eliminar.
Mr. Shiny and New 安 宇
Si conoce el sustantivo, puede modelar las oraciones para que funcionen con el adjetivo adecuado. Pero sí, habiendo estudiado griego clásico, tienes una forma diferente de la palabra basada en sustantivos masculinos, femeninos o neutros (el adjetivo toma la forma del sustantivo que modifica), y la forma difiere según su función en la oración ( sujeto, objeto, etc.). Siempre podemos encontrar casos en los que una solución funciona y otra no. Esta es la forma en que la gente de Java intentó resolver el problema. Aún debe tener cuidado con la forma en que forma los formatos de los mensajes.
Berin Loritsch
Siempre puede alimentar la solución Java con dos números enteros, donde el segundo indica el género. (Pero en realidad, el acuerdo de género suele ser menos preocupante simplemente porque el caso de uso de colocar diferentes objetos en un mensaje es menos frecuente que colocar diferentes números del mismo objeto en un mensaje)
Ken Bloom
12

Yo optaría por no codificar el mensaje, sino por proporcionar dos mensajes en un archivo de recursos separado. Me gusta

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

y luego alimentarlos en String.Format like

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

string message = String.Format(messageTemplate, noofitemsselected)

Creo que este enfoque es más fácil de localizar y mantener. Todos los mensajes de la interfaz de usuario estarían en una única ubicación.

Jens
fuente
+1, me gusta este enfoque. Aunque, necesitaría realizar un seguimiento de los equivalentes de nombres de recursos.
Predeterminado el
11

Puede eludir el problema por completo redactando el mensaje de manera diferente.

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

Lo primero que sugeriría es: use string.Format. Eso te permite hacer algo como esto:

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

Además, en las aplicaciones de WPF, he visto sistemas en los que una cadena de recursos estaría delimitada por tuberías para tener dos mensajes: un mensaje en singular y uno en plural (o un mensaje cero / único / muchos, incluso). Luego, se podría usar un convertidor personalizado para analizar este recurso y usar la cadena relevante (formateada), por lo que su Xaml es algo como esto:

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

Para inglés, muchas respuestas arriba. Para otros idiomas es más difícil, ya que los plurales dependen del género del sustantivo y de la terminación de la palabra. Algunos ejemplos en francés:

Masculino regular:

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

Regular femenino

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

Masculino irregular (termina con 's')

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

El mismo problema existe en la mayoría de las lenguas latinas y se agrava en alemán o ruso, donde hay 3 géneros (masculino, femenino y neutro).

Deberá tener cuidado si su objetivo es manejar algo más que inglés.

smirkingman
fuente
Al menos en mi caso, esto no es realmente un problema. Para cada texto que quiera insertar el número, sabré cuál es el sustantivo al generar la cadena. Pero para hacer una solución más general, estoy de acuerdo con usted, que hacer que funcione para "todos" los idiomas puede ser una tarea muy difícil, si no imposible.
Øyvind Bråthen
1
O tome el polaco, donde la forma plural del sustantivo utilizado es diferente según el número. : /
UpTheCreek
5

Para poder tener mensajes pluralizados que se puedan localizar correctamente, mi opinión es que sería prudente crear primero una capa de indirección entre el número y un mensaje.

Por ejemplo, use una constante de algún tipo para especificar qué mensaje desea mostrar. Obtenga el mensaje usando alguna función que ocultará los detalles de implementación.

get_message(DELETE_WARNING, quantity)

A continuación, cree un diccionario que contenga los posibles mensajes y variaciones, y haga que las variaciones sepan cuándo deben usarse.

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

Ahora simplemente puede encontrar la clave que corresponde a quantitye interpolar el valor de quantitycon ese mensaje.

Este ejemplo simplificado e ingenuo, pero realmente no veo ninguna otra forma sensata de hacer esto y poder proporcionar un buen soporte para L10N e I18N.

Davor Lucic
fuente
5

Tendrá que traducir la función a continuación de VBA a C #, pero su uso cambiaría a:

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

Tengo una función VBA que utilizo en MS Access para hacer exactamente lo que estás hablando. Sé que me cortarán en pedazos por publicar VBA, pero aquí va de todos modos. El algoritmo debería ser evidente a partir de los comentarios:

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

El uso se cortó un poco en los comentarios del código anteriores, así que lo repetiré aquí:

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

Sí, esta solución ignora los idiomas que no son el inglés. Si eso importa depende de sus requisitos.

mwolfe02
fuente
4

Puede generar el plural automáticamente, consulte, por ejemplo. generador plural .

Para ver las reglas de generación de plural, consulte wikipedia

string msg = "Do you want to delete " + numItems + GetPlural(" item", numItems) + "?";
thumbmunkeys
fuente
Me gusta usar este método si la aplicación no está internacionalizada. Puralizar da como resultado una aplicación más pulida.
cspolton
1
Es realmente difícil internacionalizar esto, y a menudo falla en inglés, por ejemplo, "Tienes pedidos + numMice + GetPlural (" mouse ", numMice)"
James Anderson
@James Anderson: Ese no es el mejor ejemplo gramaticalmente ;-) No caigas en la trampa de pensar que usar un método GetPural es el único método que puedes usar.
cspolton
junto con algunas funciones más para manejar algunos casos de esquina más, creo que esta es una muy buena solución, aunque no más corta.
lalli
4

¿Qué tal una forma más genérica? Evite la pluralización en la segunda oración:

Número de elementos seleccionados para eliminar: noofitemsselected.
¿Estás seguro?

Descubrí que hacerlo de esta manera coloca el número al final de la línea, lo cual es realmente fácil de detectar. Esta solución funcionaría con la misma lógica en cualquier idioma.

Danosaure
fuente
"Elementos seleccionados para eliminar:" no suena bien, la oración indica una lista de nombres, pero se imprime un número. Incluso si se cambia a "Número de elementos a eliminar:", los "elementos" siguen siendo incómodos.
lalli
@lalli: Sí, la redacción no es perfecta y ninguna de las soluciones proporcionadas suena perfecta. Solo sugiero ponerlo en una forma como etiqueta y valor. Tienes razón al agregar Number(estaba respondiendo mientras mecía a mi bebé para dormir).
Danosaure
4

Mi enfoque general es escribir una "función única / plural", como esta:

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

Luego, en el cuerpo del mensaje llamo a esta función:

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

Esto no es mucho mejor, pero al menos, (a) pone la decisión en una función y así despeja un poco el código, y (b) es lo suficientemente flexible para manejar plurales irregulares. es decir, es bastante fácil decir sustantivo (n, "niño", "niños") y cosas por el estilo.

Por supuesto, esto solo funciona para inglés, pero el concepto es fácilmente extensible a idiomas con terminaciones más complejas.

Se me ocurre que podría hacer que el último parámetro sea opcional para el 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;
}
Arrendajo
fuente
1
Me gusta su última parte en la que usa un valor predeterminado para "despejar" el código en caso de la operación predeterminada de agregar una s para pluralizar el sustantivo.
Øyvind Bråthen
4

Internacionalización

Supongo que desea soporte para la internacionalización, en cuyo caso diferentes idiomas tienen diferentes patrones de plurales (por ejemplo, una forma plural especial para 2 de algo, o idiomas más complicados como el polaco), y no puede confiar en aplicar un patrón simple a su cadena arreglarlo.

Puede utilizar la ngettextfunción GNU Gettext y proporcionar dos mensajes en inglés en su código fuente. Gettext proporcionará la infraestructura para elegir entre otros (potencialmente más) mensajes cuando se traduzca a otros idiomas. Consulte http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html para obtener una descripción completa del soporte plural de GNU gettext.

GNU Gettext está bajo la LGPL. ngettextse nombra GettextResourceManager.GetPluralStringen el puerto C # de Gettext.

(Si no necesita soporte de localización y no quiere usar Gettext de inmediato, escriba su propia función que haga esto para inglés y pase dos mensajes completos , de esa manera si necesita l10n más tarde, puede agregar reescribiendo una sola función).

Ken Bloom
fuente
3

¿Qué tal escribir una función como

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

.. y utilizarlo siempre que lo necesite?

string message = "You have selected " + GetOutputMessage(noofitemsselected,"item","items") + ". Are you sure you want to delete it/them?";
Pavel Morshenyuk
fuente
3
no pensaste en eso, ¿verdad, jajaja? Tienes una función para ordenar multiplicaciones o no para la oración, luego pones "eso / ellos" al final lol
Barkermn01
Solo debe pasar dos mensajes para toda la oración a esta función.
Ken Bloom
Fue solo un ejemplo. Me doy cuenta de que la variante de enviar frases completas es más correcta.
Pavel Morshenyuk
3

Para el primer problema, me refiero a Pluralizar, puedes usar Inflector .

Y para el segundo, puede usar una extensión de representación de cadena con un nombre como ToPronounString.

Yogesh
fuente
3

Un miembro de nuestro equipo me planteó exactamente la misma pregunta ayer.

Desde que volvió a aparecer aquí en StackOverflow, pensé que el universo me estaba diciendo que tuviera una oportunidad para producir una solución decente.

Rápidamente armé algo y de ninguna manera es perfecto, sin embargo, podría ser útil o generar alguna discusión / desarrollo.

Este código se basa en la idea de que puede haber 3 mensajes. Uno para cero artículos, uno para un artículo y uno para más de un artículo que siguen la siguiente estructura:

singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural

He creado una clase interna para probar con el fin de imitar la clase de recursos. Todavía no he probado esto con un archivo de recursos real, así que aún no he visto el resultado completo.

Aquí está el código (actualmente he incluido algunos genéricos donde sé que podría haber especificado el tercer parámetro simplemente como un Tipo y también el segundo parámetro es una cadena, creo que hay una manera de combinar estos dos parámetros en algo mejor, pero yo ' Volveré a eso cuando tenga un momento libre.

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

Prueba de clase de recurso:

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

y mi método de ejecución rápida

void Main()
{
    var message = GetMessage(56, "Tester",typeof(TestMessenger));
    message.Dump();
}
Jamie Dixon
fuente
Si desea que esto sea realmente completo, también debe agregar un mensaje para singlePropertyName_Allque sea aún más obvio.
Danosaure
2

Desde mi punto de vista, su primera solución es la más adecuada. Lo que digo es que, en caso de que necesite que la aplicación admita varios idiomas, la segunda opción puede ser laboriosa. Con el primer enfoque, es fácil localizar el texto sin mucho esfuerzo.

Illuminati
fuente
2

Podría optar por un mensaje más genérico como "¿Está seguro de que desea eliminar los elementos seleccionados?".

Pedro
fuente
3
Esto ciertamente funciona, pero creo que la idea del autor de la pregunta de mostrar la cantidad de elementos que están a punto de eliminarse de un vistazo es buena. Más de una vez, intenté borrar un archivo de mi escritorio y accidentalmente borré más de ese archivo.
Cody Gray
2

Depende de lo lindo que sea el mensaje que quieras tener. Del más fácil al más difícil:

  1. Vuelva a escribir su mensaje de error para evitar la pluralización. No es tan agradable para tu usuario, pero más rápido.

  2. Utilice un lenguaje más general, pero aún incluya los números.

  3. Utilice un sistema de "pluralización" e inflector ala Rails, para que pueda decir pluralize(5,'bunch')y obtener 5 bunches. Rails tiene un buen patrón para esto.

  4. Para la internacionalización, debe mirar lo que ofrece Java. Eso admitirá una amplia variedad de idiomas, incluidos los que tienen diferentes formas de adjetivos con 2 o 3 elementos. La solución "s" está muy centrada en el inglés.

La opción que elija dependerá de los objetivos de su producto. - ndp

ndp
fuente
2

¿Por qué querría presentar un mensaje que los usuarios realmente puedan entender? Va en contra de los 40 años de historia de la programación. Nooooo, tenemos algo bueno, no lo estropees con mensajes comprensibles .


(j / k)

John Alexiou
fuente
+1: bueno ver algo de humor aquí también. Pero incluso si está bromeando, entiendo su punto subyacente. Muchos programas creados durante años tienen mensajes extremadamente malos. Por lo general, porque se vuelven demasiado técnicos para que un usuario normal los entienda de todos modos.
Øyvind Bråthen
Buen punto. Siempre me encanta cuando recibo un mensaje como "Error 494-B en la entrada del usuario": agrega ese pequeño misterio adicional sobre lo que está mal que hace la vida mucho más interesante. Recientemente recibí un error al intentar crear una contraseña que simplemente decía "La contraseña no cumple con los requisitos de seguridad". No hay indicios de qué requisito no estaba cumpliendo. Mi contraseña incluía letras mayúsculas y minúsculas y varios dígitos. Intenté agregar un personaje secial. Aún no. Finalmente pasó cuando BORRÉ un carácter. Creo que tenían la regla de que no se puede tener el mismo personaje dos veces seguidas.
Jay
2

Hazlo como se hace en World of Warcraft:

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

Se vuelve un poco más corto con

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

Un enfoque que no he visto mencionado sería el uso de una etiqueta de sustitución / selección (por ejemplo, algo como "Estás a punto de aplastar {0} [? I ({0} = 1): / cactus / cacti /]". (en otras palabras, tenga una expresión similar a un formato que especifique la sustitución en función de si el argumento cero, tomado como un número entero, es igual a 1). He visto este tipo de etiquetas en los días anteriores a .net; no tengo conocimiento de ninguna estándar para ellos en .net, ni conozco la mejor manera de formatearlos.

Super gato
fuente
0

Pensaría fuera de la caja por un minuto, todas las sugerencias aquí son hacer la pluralización (y preocuparse por más de 1 nivel de pluralización, género, etc.) o no usarlo en absoluto y proporcionar un buen deshacer.

Seguiría el camino no lingual y usaría colas visuales para eso. Por ejemplo, imagina una aplicación de Iphone que seleccionas elementos limpiando el dedo. antes de eliminarlos con el botón de eliminación maestro, "agitará" los elementos seleccionados y le mostrará un cuadro de interrogación titulado con los botones V (ok) o X (cancelar) ...

O, en el mundo 3D de Kinekt / Move / Wii - imagina seleccionar los archivos, mover tu mano al botón de borrar y que te digan que muevas tu mano sobre tu cabeza para confirmar (usando los mismos símbolos visuales que mencioné antes. de pedirle que elimine 3 archivos, le mostrará 3 archivos con una X roja medio transparente flotando y le dirá que haga algo para confirmar.

Eran Medan
fuente