String.Format:十六进制 ("X") 格式说明符和零 (0)

String.Format: Hexadecimal ("X") Format Specifier and Zero (0)

现在,在将零格式化为十六进制字符串时,String.Format 遇到了一个奇怪的问题。请看下面的例子:

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

上面的代码在 HighPart 为零的情况下工作正常,但以下两个给我一个错误的结果:

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

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

例如 LowPart 为 50,HighPart 为 0,这两个都将 return "{32-X}" 而不是 "{32-0}".

我不知道 "Why" 会发生这种情况。我也尝试用谷歌搜索但没有找到答案。所以我来这里看看有没有人有这方面的线索。

顺便说一句,我正在使用 VS2015 和 .Net4.5


编辑:原来问题出在字符串的结尾 }} 上。不过对我来说还是很奇怪。 似乎是格式化引擎中的错误,就好像我在中间添加了一个 space 一样,它会起作用。喜欢:$"{{{LowPart:X}-{HighPart:X} }}"

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

returns 32. 十进制的50就是十六进制的32,因为2*16^0+3*16^1 = 2 + 48 = 50

理解题意后编辑:

我相信此页面包含答案 (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.

所以“{1:X}}}”被解释为 "X}",因为它试图应用无法识别的 "X}"。同样的情况发生在 String.Format("{0:HELLO}",50)

解释这个问题的功劳归功于 Hans Kesting 在 中的回答,因此我将问题标记为可能重复。