Reputation: 919
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 ?
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
}
Upvotes: 5
Views: 289
Reputation: 819
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.
Upvotes: 0
Reputation: 38767
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.
Upvotes: 7