How is the new C# Span different from ArraySegment?

前端 未结 3 1797
清酒与你
清酒与你 2021-02-06 21:50

I am having trouble conceptualizing the usages for the new Span in C#.

  1. What construct(s) does it replace? Is ArraySegment now obsolete?

  2. What fu

3条回答
  •  被撕碎了的回忆
    2021-02-06 22:25

    Take also into consideration while deciding whether to use Span the limitations that applied to ref structs in C#:

    https://docs.microsoft.com/en-us/dotnet/api/system.span-1?view=netcore-2.2

    Span is a ref struct that is allocated on the stack rather than on the managed heap. Ref struct types have a number of restrictions to ensure that they cannot be promoted to the managed heap, including that they can't be boxed, they can't be assigned to variables of type Object, dynamic or to any interface type, they can't be fields in a reference type, and they can't be used across await and yield boundaries. In addition, calls to two methods, Equals(Object) and GetHashCode, throw a NotSupportedException.

    Important

    Because it is a stack-only type, Span is unsuitable for many scenarios that require storing references to buffers on the heap. This is true, for example, of routines that make asynchrous method calls. For such scenarios, you can use the complimentary System.Memory and System.ReadOnlyMemory types.

    For spans that represent immutable or read-only structures, use System.ReadOnlySpan.

    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref?view=netcore-2.2#ref-struct-types

    Adding the ref modifier to a struct declaration defines that instances of that type must be stack allocated. In other words, instances of these types can never be created on the heap as a member of another class. The primary motivation for this feature was Span and related structures.

    The goal of keeping a ref struct type as a stack-allocated variable introduces several rules that the compiler enforces for all ref struct types.

    • You can't box a ref struct.
    • You cannot assign a ref struct type to a variable of type object, dynamic, or any interface type.
    • ref struct types cannot implement interfaces.
    • You can't declare a ref struct as a member of a class or a normal struct.
    • You cannot declare local variables that are ref struct types in async methods. You can declare them in synchronous methods that return Task, Task or Task-like types.
    • You cannot declare ref struct local variables in iterators.
    • You cannot capture ref struct variables in lambda expressions or local functions.
    • These restrictions ensure you don't accidentally use a ref struct in a manner that could promote it to the managed heap.

    You can combine modifiers to declare a struct as readonly ref. A readonly ref struct combines the benefits and restrictions of ref struct and readonly struct declarations.

提交回复
热议问题