C# 如何创建内存<;T>;从一个跨度<;T>;?

C# 如何创建内存<;T>;从一个跨度<;T>;?,c#,.net,.net-core,C#,.net,.net Core,我正在尝试重载解析方法,以便在字符串版本之外使用ReadOnlySpan参数。问题在于,实现使用字典作为解析逻辑 我尝试将它切换到字典,但当然,它不能作为ReadOnlySpan作为泛型参数,因为它是一个仅用于堆栈的对象。然后我切换到使用允许的ReadOnlyMemory。然后我实现了一个基本的Ordinal比较器,但是现在从ReadOnlySpan参数创建ReadOnlyMemory时遇到了问题。这可能吗 更新 这似乎是不可能的。为了支持我在上面发布的场景,我将更改字典,使其具有int键,这是

我正在尝试重载解析方法,以便在
字符串
版本之外使用
ReadOnlySpan
参数。问题在于,实现使用
字典
作为解析逻辑

我尝试将它切换到
字典
,但当然,它不能作为
ReadOnlySpan
作为泛型参数,因为它是一个仅用于堆栈的对象。然后我切换到使用允许的
ReadOnlyMemory
。然后我实现了一个基本的
Ordinal
比较器,但是现在从
ReadOnlySpan
参数创建
ReadOnlyMemory
时遇到了问题。这可能吗

更新


这似乎是不可能的。为了支持我在上面发布的场景,我将更改字典,使其具有int键,这是
ReadOnlySpan
的hashcode,并将该值作为一个包含嵌入元素的字符串的列表,手动解决hash代码冲突。

最近有一篇文章介绍了
Span

Span
实例只能位于堆栈上,而不能位于堆上这意味着您不能装箱Span(因此不能将
Span
与现有的反射调用API一起使用,例如,因为它们需要装箱)。这意味着类中甚至非ref-like结构中都不能有
Span
字段。这意味着您不能在Span可能隐式成为类上的字段的位置使用Span,例如通过将它们捕获到lambda中,或作为异步方法或迭代器中的局部变量(因为这些“局部变量”可能最终成为编译器生成的状态机上的字段)。这还意味着您不能将
Span
用作泛型参数,作为该类型参数的实例,它可能最终被装箱或以其他方式存储到堆中(并且当前没有可用的“
where T:ref struct
”约束)

您可以从数组中创建
内存
,并按自己的方式对其进行切片 将是一个跨度,但它是一个(非ref-like)结构,可以在 堆然后,当您想要进行同步处理时,您可以得到
Span
,例如:

static async Task<int> ChecksumReadAsync(Memory<byte> buffer, Stream stream)
{
  int bytesRead = await stream.ReadAsync(buffer);
  return Checksum(buffer.Span.Slice(0, bytesRead));
  // Or buffer.Slice(0, bytesRead).Span
}
static int Checksum(Span<byte> buffer) { ... }
静态异步任务ChecksumReadAsync(内存缓冲区、流)
{
int bytesRead=wait stream.ReadAsync(缓冲区);
返回校验和(buffer.Span.Slice(0,bytesRead));
//或buffer.Slice(0,字节读取).Span
}
静态整数校验和(跨度缓冲区){…}
我认为他的文章比我自己写答案更能说明问题


很简单。
您可以将
内存
转到
Span
,但不能反过来。

系统中应该有一个
AsMemory()
方法。MemoryExtensions
类要做到这一点,不能进行测试,因为在手机上,
AsMemory()
只接受
字符串、数组、,和
ArraySegment
s.As span live on stack必须使用ToArray()方法将其复制到堆中。数组隐式转换为ReadOnlyMemoryPut前面的短单词,以节省其他人的时间。