Search code examples
c#rangeslice

Difference between range operator and Span


consider this program

using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] array = { 1, 2, 3, 4 };
            Span<byte> span = array;
            byte[] dest = new byte[4];
            //span.CopyTo(dest);  // ok
            span.CopyTo(dest[..]);  // NO
            //span.CopyTo(dest.AsSpan());  // ok
            //span.CopyTo(dest.AsSpan()[..]);  // ok

            Console.Out.Write(BitConverter.ToString(dest));
        }
    }
}

On the // NO line I expected

01-02-03-04

but got

00-00-00-00

What's happening?


Solution

  • dest[..] creates a new array. So it's a bit like this code:

    byte[] dest = new byte[4];
    
    // This is what the range operator is doing
    byte[] actualDest = new byte[4];
    dest.CopyTo(actualDest);
    
    // dest and actualDest are separate arrays now,
    // so this doesn't affect the content of dest at all
    span.CopyTo(actualDest);
    

    A simpler (IMO) example without using spans at all:

    int[] original = new int[1];
    int[] range = original[..];
    
    // Prints False, because the variables
    // refer to separate arrays
    Console.WriteLine(range == original);
    
    range[0] = 10;
    
    // Prints 0 as the two arrays are separate.
    Console.WriteLine(original[0]);