1

我将一个数组初始化为

Double[][] myarr = Enumerable.Repeat(new double[12], 13).ToArray();

然后在一个循环中,我正在递增值,例如

myarr[0][0]++; 

这会导致 myarr[1][0]、myarr[2][0]、myarr[3][0] ..... myarr[12][0] 等所有值加一。

使用 for 循环(0-12)时不会发生此问题,我正在初始化

myarr[i] = new double[12];

为什么会这样?

4

6 回答 6

5

Other answers have explained the problem. The solution is to create a new array on each iteration, e.g.

double[][] myarr = Enumerable.Range(0, 13)
                             .Select(ignored => new double[12])
                             .ToArray();
于 2012-04-09T09:08:54.323 回答
2

随着new double[12]您创建对双精度数组的引用,然后您重复引用12 次,因此 myarr[0..n] 将引用一个内存区域。

您可以使用以下方法解决问题

static T[][] CreateArray<T>(int rows, int cols)
{
    T[][] array = new T[rows][];
    for (int i = 0; i < array.GetLength(0); i++)
        array[i] = new T[cols];

    return array;
}

或者使用每一步调用动作的自定义重复方法:

public static IEnumerable<TResult> RepeatAction<TResult>(Action<TResult> elementAction, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return elementAction();
    }
    yield break;
}
usage
RepeatAction(()=>new double[12], 12);
于 2012-04-09T09:05:21.740 回答
2

这是因为new double[12]在内存中创建了一个数组对象 - Enumerable.Repeat 只是为您提供对该数组的多个引用。

于 2012-04-09T09:06:03.593 回答
2

这是预期的行为 - 数组是一种参考类型。您正在创建一个锯齿状数组,即数组数组。外部数组的所有元素都引用同一个内部数组,即Repeat调用的第一个参数,因此内部数组的变化将反映在索引上(因为所有索引都引用同一个数组)。

于 2012-04-09T09:07:04.650 回答
1

数组是引用。在Repeat调用中,您创建一个数组并为其分配 12 次引用。但是,在您的循环中,您创建了 12 个不同的数组。

于 2012-04-09T09:05:13.650 回答
1

Repeat()基本上只是多次捕获并产生相同的元素,因此您在内存中获得了对同一对象实例的多个引用。

这是如何Repeat()实现的:

private static IEnumerable<TResult> RepeatIterator<TResult>(TResult element, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return element;
    }
    yield break;
}
于 2012-04-09T09:06:51.903 回答