除ReadOnlySpan<char>
版本外,我正在尝试重载解析方法以使用string
参数。问题在于该实现将Dictionary<string, T>
用于解析逻辑。
我尝试将其切换为Dictionary<ReadOnlySpan<char>, T>
,但由于它是仅堆栈对象,因此不允许将其作为ReadOnlySpan<char>
用作通用参数。然后,我将其切换为使用允许的ReadOnlyMemory<char>
。然后,我实现了一个基本的Ordinal
比较器,但是现在很难从ReadOnlyMemory<char>
参数创建ReadOnlySpan<char>
了。这可能吗?
更新
看来这是不可能的。为了支持我在上面发布的方案,我将更改字典以使其具有一个int键,该键是ReadOnlySpan<char>
的哈希码,并将该值设为包含嵌入在元素中的字符串的列表,并且必须手动解析哈希码冲突。
答案 0 :(得分:5)
有一篇很棒的文章介绍了MSDN Magazine article上的Span<T>
Span<T>
实例只能在堆栈上,而不能在堆上。 这意味着您无法装箱跨度((例如,Span<T>
不能与现有的反射调用API一起使用,因为它们需要装箱)。这意味着您不能在类中甚至没有类似非引用的结构中都拥有Span<T>
字段。这意味着您不能在可能会隐式成为类中字段的地方使用跨度,例如通过将它们捕获到lambda或在异步方法或迭代器中作为局部变量(因为这些“局部变量”可能最终会成为编译器生成的字段)状态机。)这也意味着您不能将Span<T>
用作通用参数,因为该类型参数的实例可能最终被装箱或以其他方式存储到堆中(并且目前没有“where T : ref struct
”约束可用)。...
您可以从数组创建
Memory<T>
并将其切片 会跨度,但是它是一个(非引用类)结构,并且可以在 堆。然后,当您想要进行同步处理时,可以得到一个Span<T>
,例如: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) { ... }
我认为他的文章比我写自己的答案更好。
您可以从Memory<T>
到Span<T>
,但不能相反。