I want to be able to type something like:
Console.WriteLine("You have {0:life/lives} left.", player.Lives);
instead of
Console.WriteLine("You have {0} {1} left.", player.Lives, player.Lives == 1 ? "life" : "lives");
so that for player.Lives == 1
the output would be: You have 1 life left.
for player.Lives != 1
: You have 5 lives left.
or
Console.WriteLine("{0:day[s]} till doomsday.", tillDoomsdayTimeSpan);
Some systems have that built-in. How close can I get to that notation in C#?
EDIT: Yes, I am specifically looking for syntactic sugar, and not a method to determine what singular/plural forms are.
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.