简体   繁体   English

C# Span2D CopyTo 未正确复制二维范围

[英]C# Span2D CopyTo not copying a 2d range correctly

I'm trying to use the Span2D type to "roll" entries in a 2d array, but it's not working as expected.我正在尝试使用Span2D类型来“滚动”二维数组中的条目,但它没有按预期工作。

By rolling I mean the following - given an array such as:通过滚动我的意思是以下 - 给定一个数组,例如:

{
    { 1, 1, 1, 1, 1 },
    { 2, 2, 2, 2, 2 },
    { 0, 0, 0, 0, 0 },
}

I would like to copy the first two rows down one row, so the top row can be repopulated.我想将前两行复制到一行中,以便可以重新填充顶行。 After the roll operation the array should look like this:滚动操作后数组应如下所示:

{
    { 1, 1, 1, 1, 1 },
    { 1, 1, 1, 1, 1 },
    { 2, 2, 2, 2, 2 },
}

The Span2d CopyTo method seems perfect for this - I create a Slice of the top two rows, and a slice of the bottom two rows, copy the first slice to the second slice. Span2d CopyTo方法似乎非常适合这个——我创建了一个顶部两行的Slice和底部两行的切片,将第一个切片复制到第二个切片。 But instead of the expected result above, I get:但是我得到的不是上面的预期结果,而是:

{
    { 1, 1, 1, 1, 1 },
    { 1, 1, 1, 1, 1 },
    { 1, 1, 1, 1, 1 },
}

Here's a runnable class that shows the problem:这是显示问题的可运行 class:

public class SpanTest
{
    public static void Main()
    {
        int[,] array =
        {
            { 1, 2, 3, 4, 5 },
            { 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0 },
        };

        var h = array.GetLength(0) - 1;
        var w = array.GetLength(1);
        Console.WriteLine($"slice height:{h} width: {w}\n-----------");

        Span2D<int> span = array;
        Console.WriteLine($"{span.ToStringMatrix()}-----------");
        
        var sourceSlice = span.Slice(0, 0, h, w);
        Console.WriteLine($"{sourceSlice.ToStringMatrix()}-----------");

        var targetSlice = span.Slice(1, 0, h, w);
        Console.WriteLine($"{targetSlice.ToStringMatrix()}-----------");
        
        sourceSlice.CopyTo(targetSlice);
        Console.WriteLine($"{span.ToStringMatrix()}-----------");

    }
}

with a helper for printing the Span2D s:使用打印Span2D的助手:

public static class Utils
{
    public static string ToStringMatrix<T>(this Span2D<T> arr)
    {
        var sb = new StringBuilder();
        for (var i = 0; i < arr.Height; i++)
        {
            for (var j = 0; j < arr.Width; j++)
            {
                sb.Append($"{arr[i, j]} ");
            }

            sb.Append(Environment.NewLine);
        }

        return sb.ToString();
    }
}

How can I make the copy operation behave as expected?如何使复制操作按预期进行? Thanks谢谢

Well, the answer is quite obvious actually - at least it was when it occurred to me at 5am this morning!好吧,答案其实很明显——至少我今天早上 5 点想到的是这样!

Span2D wraps an array, copying to itself alters the backing array during the copy process. Span2D包装一个数组,复制到自身会在复制过程中改变后备数组。 By the time the second row is copied, it already contains the contents of the first row.复制第二行时,它已经包含第一行的内容。 And hence, the first row gets propagated throughout the 2d array.因此,第一行在整个二维数组中传播。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM