C#:调用列表<T>。具有未填充列表的 Item[Int32] 有时会引发异常,但并非总是如此



所以,我已经使用以下代码了一段时间了,直到最近才抛出例外。

// median-of-medians search:
const int MOM_GROUP_SIZE = 5;
List<KeyValuePair<int, float>> mediansList = indexPositionPairs;
while (mediansList.Count > 1) // could be only one because of outer loop, so check before first (inner) iteration!
{
    List<KeyValuePair<int, float>> groupMediansList;
    int fullGroupListLength = mediansList.Count / MOM_GROUP_SIZE;
    int remainderGroupSize = mediansList.Count % MOM_GROUP_SIZE;
    if (remainderGroupSize > 0)
    {
        groupMediansList = new List<KeyValuePair<int, float>>(fullGroupListLength + 1);
        // find last group median
        int startingIndex = fullGroupListLength * MOM_GROUP_SIZE;
        mediansList.Sort(startingIndex, remainderGroupSize, comp);
        groupMediansList[fullGroupListLength] = mediansList[startingIndex + remainderGroupSize / 2];
    }
    else
    {
        groupMediansList = new List<KeyValuePair<int, float>>(fullGroupListLength);
    }
    // groups of 5:
    for (int i = 0, j = 0; i < fullGroupListLength; ++i, j += MOM_GROUP_SIZE)
    {
        mediansList.Sort(j, MOM_GROUP_SIZE, comp);
        groupMediansList[i] = mediansList[j + MOM_MEDIAN_OFFSET];
    }
    // repeat on the group medians until only one remains
    mediansList = groupMediansList;
}

现在我从以下行获得ArgumentOutOfRangeException

groupMediansList[fullGroupListLength] = mediansList[startingIndex + remainderGroupSize / 2];

特别是左侧,我正在尝试在索引上设置值。我会收到异常消息:

"索引超出范围。必须是非负的,并且小于集合的大小。 r n参数名称:索引"

阅读Microsoft的一些在线文档,似乎当index大于或等于Count时,确实应该抛出ArgumentOutOfRangeException

但是,正如您可以在代码中进一步看到的那样,我使用相同的方法来填充列表,但从未引起异常。我也非常怀疑这个特定的代码块从未被调用过,因为它需要所有数据集此代码以前使用的所有数据集具有5个自然功率。

这是我在迄今为止使用此代码的最大数据集(1366921个元素!),那么它会产生任何效果吗?(理想情况下它不应该,但您永远不知道...)

目前,我将使用阵列重新编写它,但是我想了解这里发生了什么。我一直认为,如果列表在列表上超出当前大小,则在列表上进行索引会自动扩展,我担心对我较旧的项目的影响。

首先,使用int参数INTIAL的List<T>构造函数使用指定的 apcation ,而不是 length 。这意味着结果列表始终将其初始Count的零。

其次,只有在调用AddInsert(或AddRangeInsertRange)访问索引元素时,列表不会神奇地增长。即使它们确实成长,您仍然不允许您访问CountCapacity之间的任何索引。

我怀疑第二种方法"从不引起异常",因为这是同一问题:您正在创建具有特定容量的空列表,然后立即尝试访问索引超出其数量。C#不像C ,在这里可以将其粉刷为未定义的行为:这里,每次都会抛出

由于您的算法似乎是"创建预定长度的列表,然后替换单个元素",因此数组可能更拟合。

groupMediansList = new List<KeyValuePair<int, float>>(fullGroupListLength + 1);

看来,您正在假设将列表的容量设置为fullGroupListLength + 1的假设使您可以访问指数0到fullGroupListLength。但是,容量和计数是两种不同的东西。您无法访问大于或等于groupMediansList.Count的索引。解决方案是将所需数量的值添加到列表中或使用其他集合,例如数组。

相关内容

  • 没有找到相关文章

最新更新