我可以得到一个跨度的指针吗?

时间:2019-01-18 14:19:52

标签: c# .net-standard-2.0 .net-4.6 .net-core-2.1

我有一个(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),但无法将范围传递给它,也找不到其他处理指针(和范围)的方法。

这完全有可能吗?如果可以,怎么办?

2 个答案:

答案 0 :(得分:6)

如果您使用的是C#7.3或更高版本,则可以使用对fixed语句进行的扩展,该扩展可以对类型(其中GetPinnableReference和{{1 }}有):

Span

在处理指针时,当然需要一个ReadOnlySpan上下文。

C#7.0到7.2没有此功能,但允许以下操作:

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

答案 1 :(得分:3)

尝试一下:

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