C# 连接ReadOnlySpan<;char>;
好的,.NETCore2.1已经登陆。通过它,我们获得了一种处理字符串数据的新方法,即C# 连接ReadOnlySpan<;char>;,c#,.net-core,.net-core-2.1,C#,.net Core,.net Core 2.1,好的,.NETCore2.1已经登陆。通过它,我们获得了一种处理字符串数据的新方法,即ReadOnlySpan。它非常擅长分割字符串数据,但是如何将跨度重新组合在一起呢 var hello = "Hello".AsSpan(); var space = " ".AsSpan(); var world = "World".AsSpan(); var result = ...; // How do I get "Hello World" out of the 3 above? 下面是一个.NET
ReadOnlySpan
。它非常擅长分割字符串数据,但是如何将跨度重新组合在一起呢
var hello = "Hello".AsSpan();
var space = " ".AsSpan();
var world = "World".AsSpan();
var result = ...; // How do I get "Hello World" out of the 3 above?
下面是一个.NET团队如何在内部处理此问题的示例: 使用
ReadOnlySpan
的级别很低,而且速度也很快,因此如何使用可能取决于您自己的情况。但在许多情况下,返回到string
插值和StringBuilder
(或者根本不转换为ReadOnlySpan
)可能没问题。所以
或
您可以使用这样的缓冲区来实现这一点=>
var hello = "Hello".AsSpan();
var space = " ".AsSpan();
var world = "World".AsSpan();
// First allocate the buffer with the target size
char[] buffer = new char[hello.Length + space.Length + world.Length];
// "Convert" it to writable Span<char>
var span = new Span<char>(buffer);
// Then copy each span at the right position in the buffer
int index = 0;
hello.CopyTo(span.Slice(index, hello.Length));
index += hello.Length;
space.CopyTo(span.Slice(index, space.Length));
index += space.Length;
world.CopyTo(span.Slice(index, world.Length));
// Finality get back the string
string result = span.ToString();
var hello=“hello”.AsSpan();
var space=“.AsSpan()”;
var world=“world”。AsSpan();
//首先用目标大小分配缓冲区
char[]buffer=new char[hello.Length+space.Length+world.Length];
//将其“转换”为可写范围
var span=新的span(缓冲区);
//然后在缓冲区的正确位置复制每个跨距
int指数=0;
hello.CopyTo(span.Slice(index,hello.Length));
index+=hello.Length;
CopyTo(span.Slice(index,space.Length));
索引+=空间长度;
CopyTo(span.Slice(index,world.Length));
//最后,把绳子拿回来
字符串结果=span.ToString();
通过使用arraypool重用缓冲区,您可以再次对其进行优化
char[] buffer = ArrayPool<char>.Shared.Rent(hello.Length + space.Length + world.Length);
// ...
ArrayPool<char>.Shared.Return(buffer);
char[]buffer=ArrayPool.Shared.Rent(hello.Length+space.Length+world.Length);
// ...
ArrayPool.Shared.Return(缓冲区);
我周五下午的想法:
var hello = "Hello";
var helloS = hello.AsSpan();
var spaceS = " ".AsSpan();
var worldS = "World".AsSpan();
var sentence = helloS.ToString() + spaceS.ToString() + worldS.ToString();
//Gives "Hello World"
至少根据我在LinqPad上的快速播放,以及对的快速阅读,另一个选项是使用string.Concat,它接受ReadOnlySpan作为参数。下面是从github获得的实现
internal static unsafe string Concat(ReadOnlySpan<char> str0, ReadOnlySpan<char> str1, ReadOnlySpan<char> str2)
{
var result = new string('\0', checked(str0.Length + str1.Length + str2.Length));
fixed (char* resultPtr = result)
{
var resultSpan = new Span<char>(resultPtr, result.Length);
str0.CopyTo(resultSpan);
resultSpan = resultSpan.Slice(str0.Length);
str1.CopyTo(resultSpan);
resultSpan = resultSpan.Slice(str1.Length);
str2.CopyTo(resultSpan);
}
return result;
}
内部静态不安全字符串Concat(ReadOnlySpan str0、ReadOnlySpan str1、ReadOnlySpan str2)
{
var result=新字符串('\0',已选中(str0.Length+str1.Length+str2.Length));
已修复(char*resultPtr=result)
{
var resultSpan=新范围(resultPtr,result.Length);
str0.CopyTo(resultSpan);
resultSpan=resultSpan.Slice(str0.Length);
str1.CopyTo(resultSpan);
resultSpan=resultSpan.Slice(str1.Length);
str2.CopyTo(resultSpan);
}
返回结果;
}
我编写并使用以下扩展/工具方法连接跨距:
ReadOnlySpan-otherSpan=。。。
T[]someArray=。。。
var myArray=someSpan.Concat(otherSpan、someArray等);
var myArray2=SpanTool.Concat(someArray、otherSpan等);
SpanExtensions.cs
公共静态类扩展{
[MethodImpl(MethodImplOptions.AggressiveInline)]
公共静态T[]Concat(此只读span span0,只读span span1)
=>SpanTool.Concat(span0,span1);
[MethodImpl(MethodImplOptions.AggressiveInline)]
公共静态T[]Concat(此只读span span0、只读span span1、只读span span2)
=>SpanTool.Concat(span0、span1、span2);
[MethodImpl(MethodImplOptions.AggressiveInline)]
公共静态T[]Concat(此只读span span0、只读span span1、只读span span2、只读span span3)
=>SpanTool.Concat(span0、span1、span2、span3);
[MethodImpl(MethodImplOptions.AggressiveInline)]
公共静态T[]Concat(此只读span span0、只读span span1、只读span span2、只读span span3、只读span span4)
=>SpanTool.Concat(span0、span1、span2、span3、span4);
}
SpanTool.cs
公共静态类工具{
公共静态T[]Concat(只读span span0){
var结果=新的T[span0.长度];
span0.CopyTo(结果);
返回结果;
}
公共静态T[]Concat(只读span span0,只读span span1){
var结果=新的T[span0.Length+span1.Length];
var resultSpan=result.AsSpan();
span0.CopyTo(结果);
var from=span0.长度;
span1.CopyTo(结果span.Slice(from));
返回结果;
}
公共静态T[]Concat(只读span span0、只读span span1、只读span span2){
var结果=新的T[span0.Length+span1.Length+span2.Length];
var resultSpan=result.AsSpan();
span0.CopyTo(结果);
var from=span0.长度;
span1.CopyTo(结果span.Slice(from));
from+=span1.长度;
span2.CopyTo(结果span.Slice(from));
返回结果;
}
公共静态T[]Concat(只读span span0、只读span span1、只读span span2、只读span span3){
var结果=新的T[span0.Length+span1.Length+span2.Length+span3.Length];
var resultSpan=result.AsSpan();
span0.CopyTo(结果);
var from=span0.长度;
span1.CopyTo(结果span.Slice(from));
from+=span1.长度;
span2.CopyTo(结果span.Slice(from));
from+=span2.长度;
span3.CopyTo(结果span.Slice(from));
返回结果;
}
公共静态T[]Concat(只读span span0、只读span span1、只读span span2、只读span span3、只读span span4){
var结果=新的T[span0.Length+span1.Length+span2.Length+span3.Length+span4.Length];
var resultSpan=result.AsSpan();
span0.CopyTo(结果);
var from=span0.长度;
span1.CopyTo(结果span.Slice(from));
from+=span1.长度;
span2.CopyTo(结果span.Slice(from));
from+=span2.长度;
span3.CopyTo(结果span.Slice(from));
from+=span3.长度;
span4.CopyTo(结果span.Slice(from));
返回结果;
}
}
免责声明我刚刚为我的p
var hello = "Hello".AsSpan();
var space = " ".AsSpan();
var world = "World".AsSpan();
// First allocate the buffer with the target size
char[] buffer = new char[hello.Length + space.Length + world.Length];
// "Convert" it to writable Span<char>
var span = new Span<char>(buffer);
// Then copy each span at the right position in the buffer
int index = 0;
hello.CopyTo(span.Slice(index, hello.Length));
index += hello.Length;
space.CopyTo(span.Slice(index, space.Length));
index += space.Length;
world.CopyTo(span.Slice(index, world.Length));
// Finality get back the string
string result = span.ToString();
char[] buffer = ArrayPool<char>.Shared.Rent(hello.Length + space.Length + world.Length);
// ...
ArrayPool<char>.Shared.Return(buffer);
var hello = "Hello";
var helloS = hello.AsSpan();
var spaceS = " ".AsSpan();
var worldS = "World".AsSpan();
var sentence = helloS.ToString() + spaceS.ToString() + worldS.ToString();
//Gives "Hello World"
internal static unsafe string Concat(ReadOnlySpan<char> str0, ReadOnlySpan<char> str1, ReadOnlySpan<char> str2)
{
var result = new string('\0', checked(str0.Length + str1.Length + str2.Length));
fixed (char* resultPtr = result)
{
var resultSpan = new Span<char>(resultPtr, result.Length);
str0.CopyTo(resultSpan);
resultSpan = resultSpan.Slice(str0.Length);
str1.CopyTo(resultSpan);
resultSpan = resultSpan.Slice(str1.Length);
str2.CopyTo(resultSpan);
}
return result;
}