In the first version boxing will occur.
Yes.
with interpolation this does not happen and the compiler understands what to call ToString ?
Your statement “you must call ToString ” is not correct, because you must “call” not the same ToString that you call.
using System; class Test { struct S: IFormattable { public override string ToString() => "Object.ToString"; public string ToString(string format, IFormatProvider formatProvider) => "IFormattable.ToString"; } public static void Main() { S s = new S(); Console.WriteLine($"{s}"); Console.WriteLine($"{s.ToString()}"); } }
https://ideone.com/gRz74U
Since the behavior of String.Format not part of the standard of the C # language, the compiler does not have the right to perform the optimization proposed by you, since it cannot know which ToString needs to be called and with what parameters.
Moreover, if the S type definition is in a different assembly, then at compile time the compiler will not even have enough information to determine which method to call.
string.Formatexpects an array at the input, the elements of which are of typeobject.iwill be cast toobject, and since this is a significant type, it must be packaged. In the second case, boxing does not occur, sincestringis already a reference type. - Mark Shevchenko