.NET Core 2.1中如何拼接ReadOnlySpan<char>实例?
如何拼接多个ReadOnlySpan实例?
嘿,这个问题戳中了ReadOnlySpan
方法一:手动计算长度+内存复制(性能最优)
既然是内存视图,那直接操作内存最实在:先算出所有Span的总长度,分配一块刚好够的char数组,再把每个Span依次复制进去,最后转成string就行。代码示例:
var hello = "Hello".AsSpan(); var space = " ".AsSpan(); var world = "World".AsSpan(); // 先算好总长度,避免内存浪费 int totalLength = hello.Length + space.Length + world.Length; char[] resultBuffer = new char[totalLength]; int currentPos = 0; // 逐个复制每个Span到缓冲区 hello.CopyTo(resultBuffer.AsSpan(currentPos)); currentPos += hello.Length; space.CopyTo(resultBuffer.AsSpan(currentPos)); currentPos += space.Length; world.CopyTo(resultBuffer.AsSpan(currentPos)); // 从char数组生成最终字符串 string result = new string(resultBuffer);
这种方式全程只分配一次内存(就是那个char数组),性能拉满,特别适合对性能敏感的场景。
方法二:用StringBuilder简化代码(更灵活)
如果你觉得手动复制太繁琐,.NET Core 2.1及以上的StringBuilder已经支持直接Append ReadOnlySpan
var hello = "Hello".AsSpan(); var space = " ".AsSpan(); var world = "World".AsSpan(); // 要是提前知道总长度,还可以给StringBuilder指定Capacity,避免内部扩容 StringBuilder sb = new StringBuilder(hello.Length + space.Length + world.Length); sb.Append(hello); sb.Append(space); sb.Append(world); string result = sb.ToString();
这个方法代码更清爽,适合Span数量较多或者场景比较灵活的情况,性能也不会差太多——毕竟底层也是做内存复制,提前指定Capacity还能避免额外的内存分配。
避坑提醒
- 别想着直接用
+号拼接Span,ReadOnlySpan没有重载 +运算符,这么写编译直接报错。 - 如果是超高频的拼接场景,优先选第一种方法,StringBuilder虽然方便,但内部还是有一定的封装开销(不过大部分场景下完全可以忽略)。
内容的提问来源于stack exchange,提问作者hazzik




