2

Now, here is a strange problem I have with String.Format while formatting zero as a hex string. Please take a look at the following example:

    public override string ToString()
    {
        return $"{{{LowPart:X}-{HighPart.ToString("X")}}}";
    }

Above code works alright with HighPart being zero, but the following two give me a wrong result:

    public override string ToString()
    {
        return $"{{{LowPart:X}-{HighPart:X}}}";
    }

    public override string ToString()
    {
        return string.Format("{{{0:X}-{1:X}}}", LowPart, HighPart);
    }

With LowPart being 50 for example and HighPart being 0, both of these will return "{32-X}" instead of "{32-0}".

I don't know the "Why" that this happens. I also tried googling it and found no answer. So here I am to see if anyone have a clue about this.

BTW, I am using VS2015 and .Net4.5


Edit: Turns out that the problem is with the ending }} in the string. Still strange to me though. Seems like a bug in formatting engine as if I add a space there in the middle, it will work. Like: $"{{{LowPart:X}-{HighPart:X} }}"

Soroush Falahati
  • 2,196
  • 1
  • 27
  • 38

1 Answers1

2

Console.WriteLine(string.Format("{0:X}", 50));

returns 32. 50 in decimal is 32 in hexadecimal, because 2*16^0+3*16^1 = 2 + 48 = 50

Edit after understanding what the question is about:

I believe this page holds the answer (https://msdn.microsoft.com/en-us/library/txafckwd(v=vs.110).aspx)

The way escaped braces are interpreted can lead to unexpected results. For example, consider the format item "{{{0:D}}}", which is intended to display an opening brace, a numeric value formatted as a decimal number, and a closing brace. However, the format item is actually interpreted in the following manner:

The first two opening braces ("{{") are escaped and yield one opening brace.

The next three characters ("{0:") are interpreted as the start of a format item.

The next character ("D") would be interpreted as the Decimal standard numeric format specifier, but the next two escaped braces ("}}") yield a single brace. Because the resulting string ("D}") is not a standard numeric format specifier, the resulting string is interpreted as a custom format string that means display the literal string "D}".

The last brace ("}") is interpreted as the end of the format item.

The final result that is displayed is the literal string, "{D}". The numeric value that was to be formatted is not displayed.

So the "{1:X}}}" is interpreted as "X}", because it tries to apply "X}" which is not recognized. The same happens in String.Format("{0:HELLO}",50)

The credit for explaining the issue goes to Hans Kesting's answer in How to use string.Format() to format a hex number surrounded by curly brackets? I flagged the question as possible duplicate because of this.

Community
  • 1
  • 1
Demo
  • 394
  • 1
  • 4
  • 16
  • 1
    This isn't the question, the problem is that with formatting a string ending with "}}" and using "X" with value 0, formatting engine fails to parse the string and so gives a wrong result. – Soroush Falahati Apr 19 '17 at 22:02
  • You deserve an upvote for your perseverance on finding the solution – Steve Apr 22 '17 at 13:38
  • Upvoted and accepted. I couldn't find anything relevant after searching for an hour yesterday. Thank you – Soroush Falahati Apr 22 '17 at 14:41
  • 1
    @Soroush Falahati You're welcome and thank you as well. The question got me curious. Also I wanted to redeem myself :) – Demo Apr 22 '17 at 14:46