C#:呼叫列表<;T>;。具有未填充列表的项[Int32]有时会抛出异常,但并非总是如此
所以,我已经使用下面的代码一段时间了,直到最近它才抛出异常C#:呼叫列表<;T>;。具有未填充列表的项[Int32]有时会抛出异常,但并非总是如此,c#,list,exception,outofrangeexception,C#,List,Exception,Outofrangeexception,所以,我已经使用下面的代码一段时间了,直到最近它才抛出异常 // 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 chec
// 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;
}
具体来说,在左边,我试图在索引处设置一个值。我收到异常消息:
“索引超出范围。必须为非负且小于集合的大小。\r\n参数名称:索引”
阅读其中一些,它似乎确实应该在索引
大于或等于计数
时抛出ArgumentOutOfRangeException
但是,正如您在代码中进一步看到的,我使用相同的方法填充列表,这从未导致异常。我也非常怀疑这个特定的代码块以前从未被调用过,因为它需要这个代码之前使用的所有数据集的大小都是5的自然幂
这是到目前为止我使用这段代码的最大数据集(1366921个元素!),所以这会有任何影响吗?(理想情况下不应该,但你永远不知道…)
现在,我将使用数组重新编写它,但我想了解这里发生了什么。我一直认为,如果列表超出当前大小,按索引寻址会自动扩展列表,我担心这会对我的旧项目产生什么影响。groupMediansList=new list(fullgrouplistness+1);
groupMediansList = new List<KeyValuePair<int, float>>(fullGroupListLength + 1);
看起来您是在假定将列表容量设置为fullGroupListLength+1
允许您通过fullGroupListLength
访问索引0的情况下工作的。然而,容量和计数是两件不同的事情。您无法访问大于或等于groupMediansList.Count的索引。解决方案是向列表中添加所需数量的值,或者使用不同的集合,如数组。groupMediansList=new list(fullgrouplistness+1);
看起来您是在假定将列表容量设置为fullGroupListLength+1
允许您通过fullGroupListLength
访问索引0的情况下工作的。然而,容量和计数是两件不同的事情。您无法访问大于或等于groupMediansList.Count的索引。解决方案是将所需数量的值添加到列表中,或者可能使用不同的集合,如数组。首先,采用int
参数的list
构造函数以指定的容量而不是长度初始化列表。这意味着结果列表的初始计数始终为零
其次,当您通过索引访问其元素时,列表不会神奇地增长,只有当您调用Add
或Insert
(或AddRange
或InsertRange
时,您才能了解要点)。即使它们确实增长了,您仍然不能访问Count
和Capacity
之间的任何索引
我怀疑第二种方法“从未导致异常”,因为这是同一个问题:您正在创建一个具有特定容量的空列表,然后立即尝试访问超出其计数的索引。C不象C++,在这里,它可以被粉笔地定义为未定义的行为:在这里,它将每次抛出。
由于您的算法似乎是“创建一个预定长度的列表,然后替换单个元素”,因此数组可能更合适。首先,采用int
参数的list
构造函数以指定的容量而不是长度初始化列表。这意味着结果列表的初始计数始终为零
其次,当您通过索引访问其元素时,列表不会神奇地增长,只有当您调用Add
或Insert
(或AddRange
或InsertRange
时,您才能了解要点)。即使它们确实增长了,您仍然不能访问Count
和Capacity
之间的任何索引
我怀疑第二种方法“从未导致异常”,因为这是同一个问题:您正在创建一个具有特定容量的空列表,然后立即尝试访问超出其计数的索引。C不象C++,在这里,它可以被粉笔地定义为未定义的行为:在这里,它将每次抛出。
因为您的算法似乎是“创建一个预定长度的列表,然后替换单个元素”,所以数组可能更合适。问题是,我一直在访问等于或大于Count的索引,而且它以前从未抛出异常。这段代码在其他数据集上运行良好,为了填充列表,它总是多次访问等于count的索引。我真正想知道的是它为什么不一致。@TravisReed我希望看到一个例子来证明你的断言,你有时可以访问大于或等于Count的索引。嗯。。。它似乎不起作用。现在我开始怀疑自己的理智了。问题是,我一直在访问等于或大于Count的索引,而且它以前从未抛出异常。这段代码在其他数据集上运行良好,为了填充列表,它总是多次访问等于count的索引。我真正想知道的是它为什么不一致。@TravisReed我希望看到一个例子来证明你的断言,你有时可以访问大于或等于Count的索引。嗯。。。它似乎不起作用。现在我开始怀疑我自己的理智。
groupMediansList = new List<KeyValuePair<int, float>>(fullGroupListLength + 1);