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
How to Set Web.Config File to Show Full Error Message
Limit the Number of Parallel Threads in C#
C# Generic Type Inference with Multiple Types
How to Use Timezoneinfo to Get Local Time During Daylight Saving Time
Best Practices for Serializing Objects to a Custom String Format for Use in an Output File
Why Folderbrowserdialog Dialog Does Not Scroll to Selected Folder
C# Iterate Through Class Properties
Conditionally Required Property Using Data Annotations
System.Net.Webclient Unreasonably Slow
How to Compile a C# File with Roslyn Programmatically
Methodinfo.Invoke with Out Parameter
Argumentoutofrangeexception on Initialized List
How to Get a Count of the Total Number of Digits in a Number
How Can a Wpf Usercontrol Inherit a Wpf Usercontrol