0Pricing
C# Academy · Lesson

Memory/ReadOnlyMemory emulation: zero-copy windows

Pass ArraySegment instead of arrays: create windows, implement Skip/Take/Slice, parse headers and payloads, and only copy at boundaries.

Windows over arrays

Aim: Treat arrays as memory windows.

  • Use ArraySegment<T> to pass views
  • Build tiny Skip/Take/Slice helpers
  • Parse headers/payloads without copies
  • Only copy at I/O boundaries

Skip/Take/Slice helpers

Create tiny Slice, Skip, and Take helpers to compose windows clearly.

using System;

public static class Seg
{
  public static ArraySegment<T> Slice<T>(ArraySegment<T> s, int start, int count)
  {
    if (start < 0 || count < 0 || start + count > s.Count) throw new ArgumentOutOfRangeException();
    return new ArraySegment<T>(s.Array, s.Offset + start, count);
  }

  public static ArraySegment<T> Skip<T>(ArraySegment<T> s, int n)
  {
    if (n < 0 || n > s.Count) throw new ArgumentOutOfRangeException("n");
    return new ArraySegment<T>(s.Array, s.Offset + n, s.Count - n);
  }

  public static ArraySegment<T> Take<T>(ArraySegment<T> s, int n)
  {
    if (n < 0 || n > s.Count) throw new ArgumentOutOfRangeException("n");
    return new ArraySegment<T>(s.Array, s.Offset, n);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    int[] xs = new int[] { 10, 20, 30, 40, 50 };
    ArraySegment<int> view = new ArraySegment<int>(xs, 1, 3); // 20,30,40
    ArraySegment<int> head = Seg.Take<int>(view, 2);          // 20,30
    ArraySegment<int> tail = Seg.Skip<int>(view, 1);          // 30,40
    Console.WriteLine(head.Array[head.Offset] + "," + head.Array[head.Offset + 1]);
    Console.WriteLine(tail.Array[tail.Offset] + "," + tail.Array[tail.Offset + 1]);
  }
}

All lessons in this course

  1. Span/ReadOnlySpan fundamentals (C# 6 emulation)
  2. Memory/ReadOnlyMemory emulation: zero-copy windows
  3. String-as-Span APIs (C# 6 emulation)
← Back to C# Academy