Enumerable.Repeat有一些内存问题?

时间:2012-04-09 09:00:41

标签: c# linq ienumerable

我将数组初始化为

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

然后在循环中我正在增加像

这样的值
myarr[0][0]++; 

这导致myarr [1] [0],myarr [2] [0],myarr [3] [0] ..... myarr [12] [0]等所有值增加1。

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

myarr[i] = new double[12];

为什么会这样?

6 个答案:

答案 0 :(得分:5)

其他答案解释了这个问题。解决方案是在每次迭代时创建一个新数组,例如

double[][] myarr = Enumerable.Range(0, 13)
                             .Select(ignored => new double[12])
                             .ToArray();

答案 1 :(得分: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;
}

或者使用自定义Repeat方法,每次调用操作:

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);

答案 2 :(得分:2)

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

答案 5 :(得分: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;
}