Clever way to append 's' for plural form in .Net (syntactic sugar)

前端 未结 14 1623
抹茶落季
抹茶落季 2021-01-30 06:53

I want to be able to type something like:

Console.WriteLine(\"You have {0:life/lives} left.\", player.Lives);

instead of

Consol         


        
相关标签:
14条回答
  • 2021-01-30 07:25

    See the Inflector class that is part of Castle ActiveRecord. It is licensed under the Apache license.

    It has a set of regular expression rules that define how words are pluralized. The version I have used has some errors in these rules though, e.g. it has a 'virus' → 'virii' rule.

    I have three extension methods which wrap Inflector, the first of which may be right up your street:

        /// <summary>
        /// Pluralises the singular form word specified.
        /// </summary>
        /// <param name="this">The singular form.</param>
        /// <param name="count">The count.</param>
        /// <returns>The word, pluralised if necessary.</returns>
        public static string Pluralise(this string @this, long count)
        {
            return (count == 1) ? @this :
                                  Pluralise(@this);
        }
    
        /// <summary>
        /// Pluralises the singular form word specified.
        /// </summary>
        /// <param name="this">The singular form word.</param>
        /// <returns>The plural form.</returns>
        public static string Pluralise(this string @this)
        {
            return Inflector.Pluralize(@this);
        }
    
        /// <summary>
        /// Singularises the plural form word.
        /// </summary>
        /// <param name="this">The plural form word.</param>
        /// <returns>Th singular form.</returns>
        public static string Singularise(this string @this)
        {
            return Inflector.Singularize(@this);
        }
    
    0 讨论(0)
  • 2021-01-30 07:26

    You can create a custom formatter that does that:

    public class PluralFormatProvider : IFormatProvider, ICustomFormatter {
    
      public object GetFormat(Type formatType) {
        return this;
      }
    
    
      public string Format(string format, object arg, IFormatProvider formatProvider) {
        string[] forms = format.Split(';');
        int value = (int)arg;
        int form = value == 1 ? 0 : 1;
        return value.ToString() + " " + forms[form];
      }
    
    }
    

    The Console.WriteLine method has no overload that takes a custom formatter, so you have to use String.Format:

    Console.WriteLine(String.Format(
      new PluralFormatProvider(),
      "You have {0:life;lives} left, {1:apple;apples} and {2:eye;eyes}.",
      1, 0, 2)
    );
    

    Output:

    You have 1 life left, 0 apples and 2 eyes.
    

    Note: This is the bare minimum to make a formatter work, so it doesn't handle any other formats or data types. Ideally it would detect the format and data type, and pass the formatting on to a default formatter if there is some other formatting or data types in the string.

    0 讨论(0)
提交回复
热议问题