Post

More C# 7 goodness - Span of T - Span<T>

Introduction

With C# 7.2 we got a new type: Span. So, what is Span? Span is a new value type that enables us to work and manage any type that represents a contiguous chunk of memory.

As Mads Torgersen has put it: Span is a window onto an existing chunk of memory. For instance a chunk of memory that array represents or any type that represents the span of variables of the same type. Span is simply pointing to existing memory. It doesn’t have its own memory.

Span is a struct and it will NOT cause heap allocation.

Span provides type-safe access to memory while maintaining the performance of arrays.

We can use Span with:

  • arrays
  • strings
  • stack allocation
  • native buffers

It is very useful because we can simply slice an existing chunk of memory and manage it, we don’t have to copy it and allocate new memory.

List of types that we can convert to Span:

  • Arrays
  • Pointers
  • stackalloc
  • IntPtr

With ReadOnlySpan we can convert all above and string:

  • Arrays
  • Pointers
  • stackalloc
  • IntPtr
  • string

Code

Pointing to existing array

Let’s see an example with array and Span:

https://gist.github.com/Ibro/187676ec710bf9dc9a27eae3f7bb37c2

That prints out all the numbers.

Using only slice of an array

We can also use a slice of that array:

https://gist.github.com/Ibro/a7317171a6abd2da581a78fbba38ca9f

This will only print out 3 values. Elements from index 1 to 3, with the element at index 3 included. Slice will not modify the array.

Span constructor

As we said, Span is only a window onto existing memory. Hence, if we want to use a Span constructor, we have to provide it with an array, or part of array or pointer to some piece of memory:

Creating new Span and copying elements from one Span to another

We can also copy elements to the new span. However, when we initialize new span we need to create a new array or give it existing one.

We will create a new array and copy elements from one span to another:

https://gist.github.com/Ibro/008aa78453cdd3f7e8492d206126dc57

Destination span points out to completely new memory location and that’s why clearing the first span will not affect the destination span.

That prints out:

https://gist.github.com/Ibro/1c17a715a85804d34f35fbcb7c70c63f

Clear and Fill

Span has methods available to clear the values of memory where it points to. For an array, it would reset all values to default ones.

We can also use fill to populate all elements with the same value.

ToArray and ToString

We can also create a new array or string from existing Span and that will actually create a new array or string in memory.

https://gist.github.com/Ibro/30b8b83ee12685a9d0259a1a6860184d

Disadvantages

Since Span is actually a struct and it does not inherit from IEnumerable, we can’t use LINQ against it. This is a big minus when compared to C# collections.

Span also has only limited number of methods available. It is really useful for saving memory but regarding manipulation of data that it points to we can’t do much.