String.Format gottach

 

I saw this recently over an internal email list and I thought I’d share it… 

A developer asks:

I’ve found a bug in the way String.Format handles close curly literals.  It’s provoked by having a format specifier on a string.  The attached code demonstrates this on .NET Framework 1.1.  The core of it goes as follows:

// BUG: "}}" to get a literal "}" doesn't work
// when ":d" (or other) format specifier is present:

string wrong = String.Format("{{{0:d}}}", 42);

Here I’d expect the produced string to be “{42}”, but instead I get “{d}”.  I first ran into this bug using the :x (hex) format specifier, so I expect others are also implicated.

Kit George, the PM for this feature responds:

 

This actually isn’t a bug.

Consider this example:

 

string right1=String.Format("{0:d!}", 42);

 

We know that’s the wrong format specifier in the middle there (d!), but if we Console.WriteLine the result, we get:

 

d!

 

Going a step further:

 

string right3=String.Format("{{{0:d!}}}", 42);           

 

produces

{d!}

 

So the first thing we know is, if you put in  a string for the specifier that is longer than one character, string.format simply prints that literal out.

 

The reason you’re item comes out the way it does, is because we resolve the escaped curly brackets in the order we’re given them. Therefore:

 

{{      is escaped

{0:d looks like formatting

}}       is escaped

}        ends the formatting section

 

Therefore, the formatting routine thinks that what’s in the formatting section is in fact:

 

0:d}

 

It therefore simply prints out d} as a literal, just like it prints out d!, if that’s what we had given it.

 

However, I have made sure the docs for this area get cleaned up to make this more clear.

Published 26 December 03 01:25 by BradA
Filed under:

Comments

# RichB said on December 28, 2003 5:17 AM:
Despite it being the correct behavior, it's not very intuitive is it? - surely a goal of .Net is to have an intuitive API and get away from Candy Manchine Interfaces. The Format function could be made more intuitive by simply not doing the token lookahead at line 1065 (ROTOR builds) inside of StringBuilder::AppendFormat(). From the looks of things, all this would involve is the removal of 3 lines of code!
# Juan Felipe said on December 30, 2003 5:26 PM:
Maybe it isn't a bug, but it really is unexpected. I think the "correct" behavior isn't always (at least in this case) the "desired" behavior.... and as RichB said "a goal of .Net is to have an intuitive API". So in this case, the "correct" behavior is indeed a BUG. (at least for me)
# Luke Hutteman said on December 31, 2003 10:57 AM:
ouch - talk about non-intuitive implementations... Are there any format-strings that would actually need an embedded "}"? if not, I see no reason not to simply take the first } after a format specifier as the end of that specifier... At least that way it would be possible to put a "}" after a format-specifier (which is bound to be a much more common case as someone wanting one inside the specifier)
# Michael Entin said on January 4, 2004 5:04 AM:
I agree with previos three posters - maybe it is not an implementation bug, but it surely looks like design bug to me. Since format specifiers don't use "}", it should not be treated as part of such. By the way, is there a reasonable workaround for those who want to print "{42}"?
# Kit George [MSFT] said on January 6, 2004 12:46 PM:
Guys, this is great feedback, thanks. You can workaround this in the meantime pretty easily: Double d = 42; Console.WriteLine("{0}{1}{2}", "{". d, "}"); However, we will look at wheter we need to change this behavior to make it more intuitive
# Brad Abrams said on January 15, 2004 1:22 AM:
New Comments to this post are disabled

Search

Go

This Blog

Syndication

Page view tracker