KVM
KVM

Reputation: 919

C#6 String interpolation + short format string bug?

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
    }

Upvotes: 5

Views: 289

Answers (2)

fdafadf
fdafadf

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

ProgrammingLlama
ProgrammingLlama

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.

Try my example.

Upvotes: 7

Related Questions