はじめに
今回はstring-interpolationの実態がどうなっているかについて取り上げたいと思います。
var x = 10; var y = 20; var str = $"{x}, {y}";
C#9時点
SharpLabにて先ほどのコードをC#9でILにコンパイルをし、C#に逆コンパイルをするという手順をとると以下のようなコードが生成されます。

なんと以下のコードは実質的に全く同じであるということが分かります。
var str = $"{x}, {y}"; var str = string.Format("{0}, {1}", x, y);
ちなみにですが、string.Formatの引数はObjectなので、xやyがスタックに配置されている場合はboxingが発生してしまいます。
String.Format メソッド (System) | Microsoft Learn
これはResultsをILに変換すると調べることができます。
IL_0000: ldc.i4.s 10 IL_0002: stloc.0 IL_0003: ldc.i4.s 20 IL_0005: stloc.1 IL_0006: ldstr "{0}, {1}" IL_000b: ldloc.0 IL_000c: box [System.Private.CoreLib]System.Int32 IL_0011: ldloc.1 IL_0012: box [System.Private.CoreLib]System.Int32 IL_0017: call string [System.Private.CoreLib]System.String::Format(string, object, object) IL_001c: pop IL_001d: ret
IL_000cとIL_0012がそれですね。
defalt(C#10.0以上)
コンパイラーを変えてみると、実は結果が変わります。
// 変換前 var x = 10; var y = 20; var str = $"{x}, {y}";
// 変換後 int value = 10; int value2 = 20; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(2, 2); defaultInterpolatedStringHandler.AppendFormatted(value); defaultInterpolatedStringHandler.AppendLiteral(", "); defaultInterpolatedStringHandler.AppendFormatted(value2); defaultInterpolatedStringHandler.ToStringAndClear();
よくわかりませんがDefaultInterpolatedStringHandlerを利用したコードに変換されました。
補間された文字列 String をインスタンスに処理するために言語コンパイラによって使用されるハンドラーを提供します。
前回と同じようにILを見てboxingが発生していないか調べてみましょう。
IL_0000: ldc.i4.s 10 IL_0002: stloc.0 IL_0003: ldc.i4.s 20 IL_0005: stloc.1 IL_0006: ldloca.s 2 IL_0008: ldc.i4.2 IL_0009: ldc.i4.2 IL_000a: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::.ctor(int32, int32) IL_000f: ldloca.s 2 IL_0011: ldloc.0 IL_0012: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendFormatted<int32>(!!0) IL_0017: ldloca.s 2 IL_0019: ldstr ", " IL_001e: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendLiteral(string) IL_0023: ldloca.s 2 IL_0025: ldloc.1 IL_0026: call instance void [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::AppendFormatted<int32>(!!0) IL_002b: ldloca.s 2 IL_002d: call instance string [System.Runtime]System.Runtime.CompilerServices.DefaultInterpolatedStringHandler::ToStringAndClear() IL_0032: pop IL_0033: ret
どこにもboxの文字がありません。つまりstring-interpolationはboxingが発生しないような修正が裏で入ったということになります。
Unityとの関係性について
Unity 2022.1の段階でもC#9.0までしか対応していません。
またDefaultInterpolatedStringHandler は.NET 6.0から、つまりC#10.0から導入されたようです。
DefaultInterpolatedStringHandler.AppendFormatted メソッド (System.Runtime.CompilerServices) | Microsoft Learn
C# 言語のバージョン管理 - C# ガイド | Microsoft Learn