C#内插字符串
前言
在.Net 6.0的时候,引入内插字符串,在 C# String.Format性能优化 ,也讲到了内插字符串,也对DefaultInterpolatedStringHandler进行了源码学习,这里为什么又为什么在说一次呢?因为在.Net 8,BCL类库中还有一些地方在内插字符串进行代码的优化. 这个在项目中经常看到字符串拼接(+=), 所以平时在写代码的时候,对于简单的字符串拼接,不要直接在进行拼接了.
内插字符串,在这里的优点,就是减少临时字符串的产生,降低GC的压力,从而提高程序的性能.
不管是不是老项目(.Net Framework),还是.Net(.Net Core),在简单的字符串拼接时,都应尽量使用这种语法$"age={0}",这样如果是老项目迁移版本到.Net后,不需要修改代码,就可以提高性能.
看看这个issue: Use string interpolation in a few more places (#82096) .在.Net BCL基础库中更多的地方使用内插字符串.

示例代码
public class StringInterpolated
{
public string Test1()
{
int a = 20;
return $"age={a}"; //这种方式就是内插字符串
}
public string Test2()
{
int a = 20;
return string.Format("age={0}", a); //在字符串比较短的时候,可以使用,短字符串时,在栈上分配空间,大字符串的使用数组池
}
public string Test3()
{
int a = 20;
return "age=" + a; //不建议使用这种方式,进行字符串拼接
}
}
使用DnSpy.exe查看编译后的代码
public class StringInterpolated
{
// Token: 0x0600003F RID: 63 RVA: 0x00002A64 File Offset: 0x00000C64
public string Test1()
{
int a = 20;
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(4, 1); //预分配字符串空间
defaultInterpolatedStringHandler.AppendLiteral("age="); //拼接常量字符串
defaultInterpolatedStringHandler.AppendFormatted<int>(a);
return defaultInterpolatedStringHandler.ToStringAndClear(); //生成字符串
}
// Token: 0x06000040 RID: 64 RVA: 0x00002AA0 File Offset: 0x00000CA0
public string Test2()
{
int a = 20;
return string.Format("age={0}", a); //使用string.Format,这种方式也是可以的,在短字符串的时候,在栈上分配空间,在大字符串的时候,也会复用池化的数组
}
// Token: 0x06000041 RID: 65 RVA: 0x00002AC8 File Offset: 0x00000CC8
public string Test3()
{
return "age=" + 20.ToString();
}
}
秋风
2023-07-23