我正在尝试重载解析方法以使用 ReadOnlySpan<char>
除了 string
之外的参数版本。问题是实现使用了 Dictionary<string, T>
用于解析逻辑。
我尝试将其切换为 Dictionary<ReadOnlySpan<char>, T>
但当然这没有用 ReadOnlySpan<char>
不允许作为通用参数,因为它是仅堆栈对象。然后我将其切换为使用 ReadOnlyMemory<char>
这是允许的。然后我实现了一个基本的 Ordinal
比较器,但现在无法创建 ReadOnlyMemory<char>
来自 ReadOnlySpan<char>
范围。这可能吗?
更新
这似乎是不可能的。为了支持我在上面发布的场景,我将更改字典以具有一个 int 键,它是 ReadOnlySpan<char>
的哈希码。并使该值成为一个列表,其中的字符串嵌入在元素中,并且必须手动解决哈希码冲突。
最佳答案
长话短说:
你可以去Memory<T>
至 Span<T>
,但反之则不然。
背景:
有一篇内容丰富的 2018 MSDN 杂志文章介绍了 Span<T>
在 2018 MSDN Magazine article
Span<T>
instances can only live on the stack, not on the heap. This means you can’t box spans (and thus can’t useSpan<T>
with existing reflection invoke APIs, for example, as they require boxing). It means you can’t haveSpan<T>
fields in classes, or even in non-ref-like structs. It means you can’t use spans in places where they might implicitly become fields on classes, for instance by capturing them into lambdas or as locals in async methods or iterators (as those “locals” may end up being fields on the compiler-generated state machines.) It also means you can’t useSpan<T>
as a generic argument, as instances of that type argument could end up getting boxed or otherwise stored to the heap (and there’s currently no “where T : ref struct
” constraint available)....
You can create a
Memory<T>
from an array and slice it just as you would a span, but it’s a (non-ref-like) struct and can live on the heap. Then, when you want to do synchronous processing, you can get aSpan<T>
from it, for example: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) { ... }
我认为他的文章比我自己写的答案更清楚。
关于c# - 如何从 Span<T> 创建 Memory<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51108568/