5

C# 6 introduced string interpolation and a shorter way to specify the format string.

IntPtr ptr = new IntPtr(0xff);

Console.WriteLine(ptr.ToString());      // 255
Console.WriteLine(ptr.ToString("x"));   // ff

Console.WriteLine($"0x{ptr.ToString("x")}"); // 0xff
Console.WriteLine($"0x{ptr:x}"); //0x255

Why the two last lines output a different result ? Am I missing something ?

Try it with DotnetFiddle

As a side note here is the source code of IntPtr ToString() in dotnet core :

public unsafe  String ToString(String format) 
    {
        #if WIN32
            return ((int)m_value).ToString(format, CultureInfo.InvariantCulture);
        #else
            return ((long)m_value).ToString(format, CultureInfo.InvariantCulture);
        #endif
    }
2
  • $"0x{(int)ptr:x}" // 0xff Commented Mar 27, 2020 at 8:15
  • 2
    You shouldn't really be comparing with ToString - it'd be more accurate to compare with string.Format("{0:x}", ptr); which also returns 255. Commented Mar 27, 2020 at 8:24

2 Answers 2

7

Your example code:

Console.WriteLine($"0x{ptr:x}");

Is equivalent to its string.Format brother:

Console.WriteLine(string.Format("0x{0:x}", ptr));

When applying your format string "x", string interpolation / string format ultimately reaches this line of code:

IFormattable formattableArg = arg as IFormattable;

Unfortunately, while IntPtr has a custom format ToString() method, it doesn't implement IFormattable, so it's basic .ToString() method is called and the format string is discarded.

See this question for more information

As vasily.sib suggested, you can use $"0x{(int)ptr:x}" instead.

Try my example.

Sign up to request clarification or add additional context in comments.

3 Comments

Since IntPtr doesn't implement IFormattable, why does ptr.ToString("x") formats to hexadecimal ?
@Kvm As I explained, it has a custom ToString method that takes a format string. I even provided a link to it in my answer so that you can read its code.
"the format string is discarded" is something that the Framework obviously ought to detect and warn about, preferably at compile time (since interpolated string are already undergoing rather heavy transformation by the compiler), but if not then it ought to spit out some warning at runtime.
0

As documentation says:

https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings

For example, use "X" to produce "ABCDEF", and "x" to produce "abcdef". This format is supported only for integral types.

Pointer is not integral type. For example:

string.Format("{0:x}", ptr)

also returns 255.

3 Comments

Since IntPtr is not an integral type, then why does ptr.ToString("x") formats to hexadecimal ?
If you want know more than the documentation, for example you can check an implementation of ToString method of IntPtr class. public unsafe string ToString(string format) { return ((long)m_value).ToString(format, CultureInfo.InvariantCulture); } It uses internally integral type (long).
Taking this line of reasoning one step further, "pointer is not numeric type", and so that documentation page is just as inapplicable as "standard date/time format strings".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.