vote up 0 vote down star

I have a situation where I need to format an integer differently depending on whether or not it's zero. Using custom numeric format strings, this can be achieved with the semicolon as a separator. Consider the following:

// this works fine but the output is decimal
string format = "{0:0000;-0000;''}";
Console.WriteLine(format,  10); // outputs "0010"
Console.WriteLine(format, -10); // outputs "-0010"
Console.WriteLine(format,   0); // outputs ""

However, the format that I want to use is hex. What I would like the output to be is more like:

// this doesn't work
string format = "{0:'0x'X8;'0x'X8;''}";
Console.WriteLine(format,  10); // desired "0x0000000A", actual "0xX8"
Console.WriteLine(format, -10); // desired "0xFFFFFFF6", actual "0xX8"
Console.WriteLine(format,   0); // desired "", actual ""

Unfortunately, when using a custom numeric format string, I am not sure how (if it's even possible) to use the hex representation of the number in the custom format string. The scenario I have doesn't permit much flexibility so doing a two-pass format isn't an option. Whatever I do needs to be represented as a String.Format style format string.

EDIT
After looking over the Mono source for NumberFormatter (the .NET implementation simply defers to internal unmanaged code) I've confirmed my suspicions. The hex format string is treated as a special case and it is only available as a standard format string and cannot be used in a custom format string. And since a three part format string can't be used with a standard format string, I'm pretty much S.O.L.

I will probably just bite the bullet and make the integer property a nullable int and use nulls where I was using zero - bleh.

flag

75% accept rate
What happens when you try the hex format? – Lazarus Jan 13 at 16:39
I updated the question with the actual output of the 2nd format. But basically, it treats the X8 (which is a valid standalone format string) as a literal. – Josh Einstein Jan 13 at 16:47

1 Answer

vote up 0 vote down

The following format string is ALMOST correct:

string format = "0x{0:X8}";
Console.WriteLine(format, 10);
Console.WriteLine(format, -10);
Console.WriteLine(format, 0);

gives:

0x0000000A

0xFFFFFFF6

0x00000000

I'm still trying to work the '' for 0.

EDIT: I am having the same issue, with the X8's becoming literals only when the format string has the seperator ';' in use. I'm just going to poke around in the .NET source and see what I can see.

EDIT 2: The follow extension method will return a string with the correct formatting, both for +'ves, -'ves and 0. The parameter length is the amount of characters required in the hex string (excluding the '0x' on the front).

    public static string ToHexString(this int source, int length)
    {
        return (source != 0) ? string.Format("0x{0:X" + length.ToString() + "}",source) : string.Empty;
    }
link|flag
Thanks for taking a look. I've been trying to do the same but I think the unfortunate reality is that the standard format string for hex is a special case that can't be reproduced with a custom format string. – Josh Einstein Jan 13 at 17:39
It appears so. I've update the answer with a small extension method that will format an int based on the rules given. – Alastair Pitts Jan 13 at 18:05
Thanks, but the formatting of the number to string is out of my hands so I can't use an extension method or IValueConverter, etc. All I can do is provide a string format to format the output. Using the 3-part custom format string I can make zeros appear as empty strings but unfortunately it looks like I'm stuck with decimal display for non-zero values. – Josh Einstein Jan 13 at 18:38
Fair enough. Odd things like this frustrate me so often. – Alastair Pitts Jan 14 at 2:01

Your Answer

Get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.