字符串插值中可避免的装箱

Che*_*hen 5 .net c# string string-interpolation

使用字符串插值使我的字符串格式看起来更加清晰,但是.ToString()如果我的数据是值类型,我必须添加调用。

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

var person = new Person { Name = "Tom", Age = 10 };
var displayText = $"Name: {person.Name}, Age: {person.Age.ToString()}";
Run Code Online (Sandbox Code Playgroud)

.ToString()使得格式更长更难看。我试图摆脱它,但它string.Format是一个内置的静态方法,我无法注入它。你对此有什么想法吗?而且既然字符串插值是 的语法糖string.Format,为什么.ToString()在生成语法糖背后的代码时不添加调用呢?我认为这是可行的。

Jan*_*Jan 2

随着最近发布的 C# 10 和 .NET 6,情况发生了变化。编译器已经过优化,可以更好地处理内插字符串。我在这里写的内容取自Stephen Toub 的一篇文章

本质上:.NET 的早期版本将内插字符串$"{major}.{minor}.{build}.{revision}"(变量均为整数)转换为类似以下内容

var array = new object[4];
array[0] = major;
array[1] = minor;
array[2] = build;
array[3] = revision;
string.Format("{0}.{1}.{2}.{3}", array);
Run Code Online (Sandbox Code Playgroud)

从 C#10 开始,编译器可以使用“插值字符串处理程序”。上面的字符串可以翻译成:

var handler = new DefaultInterpolatedStringHandler(literalLength: 3, formattedCount: 4);
handler.AppendFormatted(major);
handler.AppendLiteral(".");
handler.AppendFormatted(minor);
handler.AppendLiteral(".");
handler.AppendFormatted(build);
handler.AppendLiteral(".");
handler.AppendFormatted(revision);
return handler.ToStringAndClear();
Run Code Online (Sandbox Code Playgroud)

据作者称,这不仅消除了拳击的需要,还引入了进一步的增强功能。结果,新方法实现了“吞吐量提高 40%,内存分配减少近 5 倍”(Stephen Toub)。

而这只是冰山一角。除了插值字符串处理程序之外,C#10 还引入了对插值字符串解释的进一步优化。

因此,我不再过多担心性能,而是关注清晰度和可读性。我们很可能花费大量时间试图以代码清晰度为代价来智取编译器,但没有取得任何实质性成果。我想说,除非我们有严重的性能问题,否则我们可以使用插值字符串,而无需走复杂的弯路。

限制。当我们翻译字符串时情况可能会有所不同。那么我们的格式字符串就变成了动态资源,对吧?现在编译器无法在运行时之前解释该字符串,我们又回到了string.Format原来的情况。