docs/coding-guidelines/api-guidelines/System.Memory.md
System.Memory is a collection of types and features that make working with
buffers and raw memory more efficient while remaining type safe. The feature
specs can be found here:
ReadOnlySpan<T> is effectively the universal receiver, in that T[], T*,
Memory<T>, ReadOnlyMemory<T>, Span<T>, ArraySegment<T> can all be
converted to it. So if you can declare your API to accept a ReadOnlySpan<T>
and behave efficiently, that's best, as any of these inputs can be used with
your method.Span<T>, if you need write access in the implementation.Span<T> or
ReadOnlySpan<T>. However, since ReadOnlySpan<T>/Span<T> are stack-only
[1], this may be too limiting for the implementation. In particular, if the
implementation needs to be able to store the argument for later usage, such as
with an asynchronous method or an iterator, ReadOnlySpan<T>/Span<T> is
inappropriate. ReadOnlyMemory<T>/Memory<T> should be used in such
situations.[1] stack-only isn't the best way to put it. Strictly speaking, these types
are called ref-like types. These types must be structs, cannot be fields
in classes, cannot be boxed, and cannot be used to instantiate generic
types. Value types containing fields of ref-like types must themselves be
ref-like types.
ReadOnlySpan<T>Span<T>ReadOnlyMemory<T>Memory<T>stackalloc with Span<T> when you need small temporary
storage but you need to avoid allocations and associated life-time management.ReadOnlySpan<T> and Span<T> as Span<T>
can be implicitly converted to ReadOnlySpan<T>.ReadOnlySpan<T>/Span<T> as well as
pointers and arrays as those can be implicitly converted to
ReadOnlySpan<T>/Span<T>.