Argumentoutofrangeexception on Initialized List

ArgumentOutOfRangeException on initialized List

You cannot index into a list if that offset doesn't exist. So, for example, indexing an empty list will always throw an exception. Use a method like Add to append the item to the end of the list, or Insert to place the item in the middle of the list somewhere, etc.

For example:

var list = new List<string>();
list[0] = "foo"; // Runtime error -- the index 0 doesn't exist.

On the other hand:

var list = new List<string>();
list.Add("foo"); // Ok. The list is now { "foo" }.
list.Insert(0, "bar"); // Ok. The list is now { "bar", "foo" }.
list[1] = "baz"; // Ok. The list is now { "bar", "baz" }.
list[2] = "hello"; // Runtime error -- the index 2 doesn't exist.

Note that in your code, this is happening when you write to the Courses list, and not when you read from the Course_ID list.

c# System.ArgumentOutOfRangeException

When you do this, it's only creating an empty list:

List<string> data = new List<string>();

So if you try to assign a value using an index, you're trying to assign a value to something that doesn't exist.

Instead you should Add() as follows:

data.Add(sr.ReadLine());

EDIT:

Also, unrelated to the question asked, but I don't see you closing the StreamReader you've opened, which is always a bad practice. I suggest, instead, using a using statement which will take care of the opening and closing of the StreamReader for you. Also, getting the lineCount is redundant, you could do something like this taking advantage of the fact that you don't need to set the number of items in a list in advance.

List<string> data = new List<string>();
using (StreamReader sr = new StreamReader(path1))
{
while(!sr.EndOfStream)
data.Add(sr.ReadLine());
}

Problems with C# lists, and ArgumentOutOfRangeException

I'll add this as a new answer since this is tackling a whole different issue. Taking a look at this code:

msRect = ms;
for (int i = 0; i < plants.Count; i++)
{
foreach (Plant NewPlant in plants) // <-- this is redundant
{
if (NewPlant.BoundingBox.Intersects(msRect))
{
SelectedIndex = i;
NewPlant.Tint = Color.Black;
}
else
NewPlant.Tint = Color.White;
}

}

You are looping through 'plants' twice inside each other! Once using an index (for (int i = 0 ...) and then inside that again using an iterator (foreach (Plant NewPlant ...).

Your options are to either change GetInfo to set the right index by using a single loop:

msRect = ms;
for (int i = 0; i < plants.Count; i++)
{
Plant NewPlant = plants[i];
if (NewPlant.BoundingBox.Intersects(msRect))
{
SelectedIndex = i;
NewPlant.Tint = Color.Black;
}
else
NewPlant.Tint = Color.White;
}

Or do the same thing and short circuit the need for SelectPlant() and SelectedIndex in the first place:

msRect = ms;
foreach (Plant NewPlant in plants) // no need for indexes
{
if (NewPlant.BoundingBox.Intersects(msRect))
{
SelectedPlant = NewPlant; // this is everything you need
NewPlant.Tint = Color.Black;
}
else
NewPlant.Tint = Color.White;
}

You do however need to be careful using a 'global' variable like SelectedPlant to capture this logic. You're better off changing the whole GetInfo method to return the selected plant, rather than having it modify SelectedPlant directly. That is, change the method signature to return Plant not void, and change SelectPlant = NewPlant in the code above to return NewPlant. Or for even more fun as a single line:

return plants.Where(p => p.BoundingBox.Intersects(ms))

Why does a call to my ListPoint.Clear() throws an ArgumentOutOfRangeException?

I think your exception is when you try to access your temp items, List.Clear() doesn't throw ArgumentOutOfRangeException because implements first IList.Clear() and finally ICollection.Clear(), and they just throw NotSupportedException from .net2 till now not ArgumentOutOfRangeException, If you call your method in different threads I guess your problem is within this lines:

    while(!(visited.Contains(temp[0]) && visted.Contains(temp[1])...){
//calculate some stuff
for(int j = 0; j <4;j++)
visited.Add(temp[j]);

and you can solve it by surrounding this part in lock block.

Also it's better to use visited.Intersect(temp).Count ==0 instead of your long if condition.

Edit: By your updated question problem is clear:

while(... (current != points[i + 1])) ooopps

when i = n - 1, points[i + 1] is out of range.

Assigning values to a list vs an array and ArgumentOutOfRangeException

Taking a look at the source code for List(of T), your see that the indexed property getter/setters look like this:

    // Sets or Gets the element at the given index.
//
public T this[int index] {
get {
// Fllowing trick can reduce the range check by one
if ((uint) index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
return _items[index];
}
set {
if ((uint) index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
_items[index] = value;
_version++;
}
}

Notice that, before setting the corresponding item in the List's internal array, it first checks the private _size variable to make sure it is in range. _size is not set to the size of the array, however. Size is incremented/decremented in the List's various Add/Remove methods, so even if you instantiate a list with an initial capacity of 10, that is the internal capacity of the List's array. Here is the constructor:

    // Constructs a List with a given initial capacity. The list is
// initially empty, but will have room for the given number of elements
// before any reallocations are required.
//
public List(int capacity) {
if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
_items = new T[capacity];
}

The _size is not set (and therefore remains as its initialized value of 0) unless you either use Add/Remove/AddRange/etc. or use the constructor that accepts an IEnumerable (in which case the size because the number of items in the IEnumerable).

It makes sense if you think about it. The idea of a list is so that you DON'T have to worry about the complexity (and ugliness) of numeric indexes and resizing/copying arrays when the capacity needs to change. The size of the internal array, after the List is instantiated, should be of no concern to the developer. If you want to micromanage how the internal array is utilized, then you should either create your own implementation, or just use an array.



Related Topics



Leave a reply



Submit