聪明的方法在.Net中附加复数形式的's'(语法糖)

THX*_*138 47 .net c# string-formatting

我希望能够输入类似的内容:

Console.WriteLine("You have {0:life/lives} left.", player.Lives);
Run Code Online (Sandbox Code Playgroud)

代替

Console.WriteLine("You have {0} {1} left.", player.Lives, player.Lives == 1 ? "life" : "lives");
Run Code Online (Sandbox Code Playgroud)

所以对于player.Lives == 1输出将是:You have 1 life left.
for player.Lives != 1:You have 5 lives left.

要么

Console.WriteLine("{0:day[s]} till doomsday.", tillDoomsdayTimeSpan);
Run Code Online (Sandbox Code Playgroud)

有些系统内置了这种功能.我有多接近C#中的符号?

编辑:是的,我特意寻找语法糖,而不是一种确定单数/复数形式的方法.

Dar*_*rov 78

您可以签出属于.NET 4.0框架的PluralizationService类:

string lives = "life";
if (player.Lives != 1)
{
    lives = PluralizationService
        .CreateService(new CultureInfo("en-US"))
        .Pluralize(lives);
}
Console.WriteLine("You have {0} {1} left", player.Lives, lives);
Run Code Online (Sandbox Code Playgroud)

值得注意的是,目前只支持英语.警告,这不适用于Net Framework 4.0 Client Profile!

您还可以编写扩展方法:

public static string Pluralize(this string value, int count)
{
    if (count == 1)
    {
        return value;
    }
    return PluralizationService
        .CreateService(new CultureInfo("en-US"))
        .Pluralize(value);
}
Run Code Online (Sandbox Code Playgroud)

然后:

Console.WriteLine(
    "You have {0} {1} left", player.Lives, "life".Pluralize(player.Lives)
);
Run Code Online (Sandbox Code Playgroud)


Guf*_*ffa 39

您可以创建一个自定义格式化程序来执行此操作:

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

}
Run Code Online (Sandbox Code Playgroud)

Console.WriteLine方法没有带有自定义格式化程序的重载,因此您必须使用String.Format:

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

输出:

You have 1 life left, 0 apples and 2 eyes.
Run Code Online (Sandbox Code Playgroud)

注意:这是使格式化程序工作的最低要求,因此它不处理任何其他格式或数据类型.理想情况下,如果字符串中存在其他格式或数据类型,它将检测格式和数据类型,并将格式设置传递给默认格式化程序.


Mua*_*Dib 7

使用@Darin Dimitrov解决方案,我会为字符串创建一个扩展....

public static Extentions
{
    public static string Pluralize(this string str,int n)
    {
        if ( n != 1 )
            return PluralizationService.CreateService(new CultureInfo("en-US"))
            .Pluralize(str);
        return str;
    }
}

string.format("you have {0} {1} remaining",liveCount,"life".Pluralize());
Run Code Online (Sandbox Code Playgroud)


Uwe*_*ayr 6

对于新奇的插值字符串,我只使用如下代码:

// n is the number of connection attempts
Console.WriteLine($"Needed {n} attempt{(n!=1 ? "s" : "")} to connect...");
Run Code Online (Sandbox Code Playgroud)

编辑:再次遇到这个问题-自从我最初发布这个答案以来,我一直在使用一种扩展方法,使它变得更加容易。此示例按特殊性排序:

static class Extensions {
    /// <summary>
    /// Pluralize: takes a word, inserts a number in front, and makes the word plural if the number is not exactly 1.
    /// </summary>
    /// <example>"{n.Pluralize("maid")} a-milking</example>
    /// <param name="word">The word to make plural</param>
    /// <param name="number">The number of objects</param>
    /// <param name="pluralSuffix">An optional suffix; "s" is the default.</param>
    /// <param name="singularSuffix">An optional suffix if the count is 1; "" is the default.</param>
    /// <returns>Formatted string: "number word[suffix]", pluralSuffix (default "s") only added if the number is not 1, otherwise singularSuffix (default "") added</returns>
    internal static string Pluralize(this int number, string word, string pluralSuffix = "s", string singularSuffix = "")
    {
        return $@"{number} {word}{(number != 1 ? pluralSuffix : singularSuffix)}";
    }
}

void Main()
{
    int lords = 0;
    int partridges = 1;
    int geese = 1;
    int ladies = 8;
    Console.WriteLine($@"Have {lords.Pluralize("lord")}, {partridges.Pluralize("partridge")}, {ladies.Pluralize("lad", "ies", "y")}, and {geese.Pluralize("", "geese", "goose")}");
    lords = 1;
    partridges = 2;
    geese = 6;
    ladies = 1;
    Console.WriteLine($@"Have {lords.Pluralize("lord")}, {partridges.Pluralize("partridge")}, {ladies.Pluralize("lad", "ies", "y")}, and {geese.Pluralize("", "geese", "goose")}");
}
Run Code Online (Sandbox Code Playgroud)

(格式相同)。输出为:

Have 0 lords, 1 partridge, 8 ladies, and 1 goose
Have 1 lord, 2 partridges, 1 lady, and 6 geese
Run Code Online (Sandbox Code Playgroud)


Tim*_*ora 5

string message = string.format("You have {0} left.", player.Lives == 1 ? "life" : "lives");
Run Code Online (Sandbox Code Playgroud)

当然,这假设您有一定数量的值来复数.


Sco*_*pey 5

我写了一个名为SmartFormat的开源库,就是这样做的!它是用C#编写的,位于GitHub上:http: //github.com/scottrippey/SmartFormat

虽然它支持多种语言,但默认为英语"复数规则".这是语法:

var output = Smart.Format("You have {0} {0:life:lives} left.", player.Lives);
Run Code Online (Sandbox Code Playgroud)

它还支持"零"数量和嵌套占位符,因此您可以执行以下操作:

var output = Smart.Format("You have {0:no lives:1 life:{0} lives} left.", player.Lives);
Run Code Online (Sandbox Code Playgroud)