Reputation: 281
I am dealing with the following class structure:
internal class C1
{
private static readonly int iMinVal = 1;
private static readonly int iMaxVal = 100;
public readonly int Number;
public C1(int iNum)
{
if (iNum < iMinVal || iNum > iMaxVal)
throw new OverflowException();
this.Number = iNum;
}
}
internal partial class C2
{
public readonly List<C1> Series = new List<C1>(10);
public C2(List<int> lNumbers)
{
lNumbers.Sort();
try
{
Series[0] = new C1(lNumbers[0]);
Series[1] = new C1(lNumbers[1]);
Series[2] = new C1(lNumbers[2]);
Series[3] = new C1(lNumbers[3]);
Series[4] = new C1(lNumbers[4]);
Series[5] = new C1(lNumbers[5]);
Series[6] = new C1(lNumbers[6]);
Series[7] = new C1(lNumbers[7]);
Series[8] = new C1(lNumbers[8]);
Series[9] = new C1(lNumbers[9]);
}
catch (OverflowException)
{
MessageBox.Show("M1!","M2");
throw;
}
}
I try to use these two classes in the following way:
private void btn_Click(object sender, EventArgs e)
{
List<C2> lRes = new List<C2>(5);
for (int iRow = 0; iRow < 5; iRow++)
{
List<int> lNumbers = new List<int> {6, 2, 5, 3, 1, 4, 10, 8, 7, 9};
lRes[iRow] = new C2(lNumbers);
}
}
But it does not work. The error message says:
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection.
I will be very appreciated if anybody could help me to find my mistake.
Upvotes: 0
Views: 97
Reputation: 878
The C1 class will store an integer number, no issue on that.
The C2 class will store a List of C1 objects. It is instantiated on declaration, giving it the size of 10. Be careful: it is still empty, no matter the size you set.
So, the dirty filling on C2 constructor, will correctly raise the exception. See the working code:
Series.Add(new C1(lnumber[0]));
...
Series.Add(new C1(lnumber[9]));
As suggested by Dmitry, it would be much better to use the Linq approach.
On btn_Click method, you are making the same mistake. The lRes List is correctly initialized and sized, but still empty. So, you have to apply the same fix seen before:
lRes.Add(new C2(lNumbers);
Upvotes: 1
Reputation: 186668
Well, line
public readonly List<C1> Series = new List<C1>(10);
means "Create list with 0 items, but reserve space for 10
items (in order to not reallocating memory)".
Please, note that Series
doesn't have any items, and that's why
Series[0] = new C1(lNumbers[0]);
will throw exception (Series[0]
doesn't exist since 0
is out of range). You should Add
items, e.g. quick (and dirty) patch
public C2(List<int> lNumbers) {
lNumbers.Sort();
try
{
Series.Clear();
Series.Add(new C1(lNumbers[0])));
Series.Add(new C1(lNumbers[1]));
Series.Add(new C1(lNumbers[2]));
Series.Add(new C1(lNumbers[3]));
Series.Add(new C1(lNumbers[4]));
Series.Add(new C1(lNumbers[5]));
}
catch (OverflowException)
{
MessageBox.Show("M1!","M2");
throw;
}
}
a better approach is Linq:
// IEnumerable<int> - let's generalize: what if we want to pass an array?
public C2(IEnumerable<int> lNumbers) {
// public method arguments validation
if (null == lNumbers)
throw new ArgumentNullException(nameof(lNumbers));
try {
Series = lNumbers
.OrderBy(item => item)
//.Take(10) // uncomment, if you want to take just top 10 items, not more
.Select(item => new C1(item))
.ToList();
}
catch (OverflowException) {
MessageBox.Show("M1!","M2");
throw;
}
}
Upvotes: 2
Reputation: 1073
You code is confusing (at least for me). But the first thing I would change is the way you "add" elements to your list. You should use the Add method to add elements to your list. Also there is no reason to create a new List lNumbers each for iteraction.
Upvotes: 1
Reputation: 1593
Is it because you are doing Row < 5
but there are 6 of these lines Series[0] = new C1(lNumbers[0]);
So is the Series[5] = new C1(lNumbers[5]);
outside the index causing that error?
EDIT: Also this line is incorrect in OP.
List<**C2**> lRes = new List<**C1**>(5);
Upvotes: 1
Reputation: 180
Series is a list of C1 items, i would use Series.Add() instead on Series[0],[1] etc, or youre basically using a list as if it was an array
Upvotes: 1