跨度和二维数组

Mic*_*ick 3 .net c# arrays multidimensional-array system.memory

是否可以将新的System.Memory Span结构与二维数据数组一起使用?

double[,] testMulti = 
    {
        { 1, 2, 3, 4 },
        { 5, 6, 7, 8 },
        { 9, 9.5f, 10, 11 },
        { 12, 13, 14.3f, 15 }
    };

double[] testArray = { 1, 2, 3, 4 };
string testString = "Hellow world";

testMulti.AsSpan(); // Compile error
testArray.AsSpan();
testString.AsSpan();
Run Code Online (Sandbox Code Playgroud)

尽管testArray和testString具有AsSpan扩展名,但testMulti不存在此类扩展名。

Span的设计是否仅限于处理一维数据数组?
我还没有找到使用Span处理testMulti数组的明显方法。

Cha*_*ace 8

为此,您可以使用 newMemoryMarshal.CreateSpan和。MemoryMarshal.GetArrayDataReference

public static Span<T> AsSpan<T>(this Array array)
{
    return MemoryMarshal.CreateSpan(ref Unsafe.As<byte, T>(ref MemoryMarshal.GetArrayDataReference(array)), array.Length);
}
Run Code Online (Sandbox Code Playgroud)

点网小提琴

这适用于数组的所有维度。如果您希望泛型类型推断起作用,则需要为每个等级(维度级别)提供单独的函数,例如AsSpan<T>(this T[,] array)AsSpan<T>(this T[,,] array)


AAA*_*ddd 5

您可以Span使用非托管内存创建一个。这将使您可以随意切片和切块

unsafe
{
    Span<T> something = new Span<T>(pointerToarray, someLength); 
}
Run Code Online (Sandbox Code Playgroud)

完整演示

unsafe public static void Main(string[] args)
{
   double[,] doubles =  {
         { 1, 2, 3, 4 },
         { 5, 6, 7, 8 },
         { 9, 9.5f, 10, 11 },
         { 12, 13, 14.3f, 15 }
      };

   var length = doubles.GetLength(0) * doubles.GetLength(1);

   fixed (double* p = doubles)
   {
      var span = new Span<double>(p, length);
      var slice = span.Slice(6, 5);

      foreach (var item in slice)
         Console.WriteLine(item);
   }
}
Run Code Online (Sandbox Code Playgroud)

输出量

7
8
9
9.5
10
Run Code Online (Sandbox Code Playgroud)

其他选择是将其重新分配给一个维数组,应对惩罚,并且不要通过

  • BlockCopy
  • 或p / memcpy直接调用并使用unsafe和指针
  • Cast<T> 例如 multiDimensionalArrayData.Cast<byte>().ToArray()

对于大型阵列,前2个将表现更好。