Reputation: 443
Given:
double price = 5.05;
Console.Write($"{{Price = {price:C}}}");
and the desired output: {Price = $5.05}
Is there any way to associate the last two curly braces as an escaped '}' so the interpolation works as intended? As it stands, the first two are escaped(I assume?), and the output is :{Price = C}
Console.Write($"{{Price = {price:C} }}");
works as expected, but with the extra space. And I can concatenate the tail brace, which I consider a poor man's solution. Is there a colloquial rich man's solution? Thanks.
Upvotes: 2
Views: 1145
Reputation: 3293
This arises because of an "oddity" in the behavior of string.Format, and our desire to have a precise 1-to-1 mapping between interpolations and inserts in the generated format string. In short, the language behavior precisely models the behavior of string.Format.
In an interpolation (the thing inside the curly braces), the expression ends either at a colon (which starts a format string), or a close curly brace. In the latter case a doubled curly brace has no special meaning because it isn't inside a literal part of the string. So three curly braces in a row would be interpreted as a close to the interpolation, followed by a literal (escaped by doubling) close curly brace. But after the colon the format string is given for that interpolation, and that format string is any string, and it is terminated by a close curly brace. If you want a close curly brace inside your format string, you simply double it up. Which is what you have unintentionally done.
CoolBots gave the best way of handling this https://stackoverflow.com/a/42993667/241658
Read the "Escaping Braces" section of https://msdn.microsoft.com/en-us/library/txafckwd(v=vs.110).aspx for an explanation of precisely this issue.
Upvotes: 4
Reputation: 1062770
Curious workaround:
var p = price.ToString("C");
Console.Write($"{{Price = {p}}}");
For some reason, $"{{Price = {p}}}"
and $"{{Price = {p:C}}}"
have different associativity outcomes, which feels like a compiler bug. I'll ask around! Note that it is consistent with how string.Format
applies the same rule, so it might be intentionally propagating an earlier framework oddity.
Upvotes: 3
Reputation: 357
When there are some problems with C# 6 syntax why not to use traditional string.Format() instead?
double price = 5.05;
Console.WriteLine(string.Format("{{Price = {0}}}", price.ToString("C")));
Upvotes: 0
Reputation: 3194
Well you can try with less used escape characters. Maybe \b will work as it doesn't print anything and it had no function for a really long time. Something like:
double price = 5.05;
Console.Write($"{{Price = {price:C}\b}}");
If that doesn't work for you, you can try with special UNICODE characters like U+200B or U+FEFF:
double price = 5.05;
Console.Write($"{{Price = {price:C}\x8203}}");
Escape characters: https://blogs.msdn.microsoft.com/csharpfaq/2004/03/12/what-character-escape-sequences-are-available/
UNICODE space characters: https://www.cs.tut.fi/~jkorpela/chars/spaces.html
Upvotes: 0
Reputation: 4869
You can interpolate instead of concatenate - pass it as a string literal:
double price = 5.05;
Console.Write($"{{Price = {price:C}{"}"}");
Upvotes: 2