views:

299

answers:

1

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.

+1  A: 

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;
    }
Alastair Pitts
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
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
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
Fair enough. Odd things like this frustrate me so often.
Alastair Pitts