我可以获得指向 Span 的指针吗?

Can I get a pointer to a Span?

我有一个(ReadOnly)Span<byte>,我想从中解码一个字符串。

只有在 .NET Core 2.1 中,我才有新的重载来从中解码字符串而无需复制字节:

Encoding.GetString(ReadOnlySpan<byte> bytes);

在 .NET Standard 2.0 和 .NET 4.6(我也想支持)中,我只有经典重载:

Encoding.GetString(byte[] bytes);
Encoding.GetString(byte* bytes, int byteCount);

第一个需要将字节复制到我想避免的数组中。
第二个需要一个字节指针,所以我考虑从我的跨度中获取一个,比如

Encoding.GetString(Unsafe.GetPointer<byte>(span.Slice(100)))

...但我没能找到真正的方法。我尝试了 void* Unsafe.AsPointer<T>(ref T value),但我无法将跨度传递给它,也没有找到另一种处理指针(和跨度)的方法。

这是否可能,如果可能,如何实现?

试试这个:

Span<byte> bytes = ...;
string s = Encoding.UTF8.GetString((byte*)Unsafe.AsPointer(ref bytes.GetPinnableReference()),
    bytes.Length);

如果您使用的是 C# 7.3 或更高版本,则可以使用对 fixed 语句的扩展,该语句可以在类型上使用任何适当的 GetPinnableReference 方法(SpanReadOnlySpan 有):

fixed (byte* bp = bytes) {
    ...
}

当我们处理指针时,这当然需要 unsafe 上下文。

C# 7.0 到 7.2 没有这个,但允许以下内容:

fixed (byte* bp = &bytes.GetPinnableReference()) {
    ...
}