内插字符串处理程序:用 ref struct 实现零分配日志格式化
通过实现自定义的内插字符串处理程序(InterpolatedStringHandler),避免日志框架在不需要输出时执行字符串格式化。 · 难度:入门 · +10XP
内插字符串处理程序
C# 10 允许创建自定义的内插字符串处理程序。本教程将构建一个 LoggerInterpolatedStringHandler 结构体,它仅在日志级别启用时才实际格式化字符串。通过将该处理程序声明为 ref struct,可以避免堆分配,同时利用 AppendLiteral 和 AppendFormatted 方法延迟执行。当日志级别不满足时,所有 Append 操作均为空操作,从而消除不必要的字符串创建与装箱。
[InterpolatedStringHandler]
public ref struct LogHandler
{
private StringBuilder? builder;
public LogHandler(int literalLength, int formattedCount, Logger logger, LogLevel level, out bool shouldAppend)
{
shouldAppend = level >= logger.MinLevel;
if (shouldAppend) builder = new StringBuilder(literalLength);
}
public void AppendLiteral(string s) => builder?.Append(s);
public void AppendFormatted<T>(T t) => builder?.Append(t?.ToString());
}
// 使用:logger.Log(LogLevel.Debug, $"Value: {x}");