如何在另一个班级中创建班级列表?

时间:2019-05-16 08:35:14

标签: c# list class nested

我正在处理以下类结构:

$this->validate(Request::instance(), ['field_name'=>['required','regex:/^\d+(((,\d+)?,\d+)?,\d+)?$/']]);

我尝试通过以下方式使用这两个类:

 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;
        }
    }

但是它不起作用。 错误消息说:

  

System.ArgumentOutOfRangeException:'索引超出范围。一定是   非负数且小于集合的大小。

如果有人可以帮助我发现我的错误,我将不胜感激。

5 个答案:

答案 0 :(得分:2)

好吧,线

 public readonly List<C1> Series = new List<C1>(10);

表示“使用 0 个项目创建列表,但为10个项目保留空间(为了不重新分配内存)”。 请注意,Series 没有任何物品,这就是为什么

 Series[0] = new C1(lNumbers[0]);

将引发异常(Series[0] 不存在,因为0不在范围内)。您应该Add个项目,例如快速(肮脏的)补丁

  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;
    }
}

更好的方法是 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;
  } 
}  

答案 1 :(得分:1)

Series是C1项的列表,我会在Series [0],[1]等上使用Series.Add()代替,或者基本上使用列表,就好像它是数组一样

答案 2 :(得分:1)

是因为您正在做Row < 5,但其中有6行Series[0] = new C1(lNumbers[0]);

那么索引之外的Series[5] = new C1(lNumbers[5]);会导致该错误吗?

编辑:同样,这行在OP中是不正确的。

List<**C2**> lRes = new List<**C1**>(5);

答案 3 :(得分:1)

您的代码令人困惑(至少对我而言)。 但是我要改变的第一件事是将元素“添加”到列表的方式。 您应该使用Add方法将元素添加到列表中。 同样也没有理由为迭代创建一个新的List lNumbers。

答案 4 :(得分:1)

C1 类将存储一个整数,没有问题。

C2 类将存储 C1 对象的 List 。它在声明时实例化,大小为10。请注意:无论您设置的大小如何,它都仍然是空的。

因此, C2 构造函数上的脏填充将正确引发异常。请参阅工作代码:

Series.Add(new C1(lnumber[0]));
...
Series.Add(new C1(lnumber[9]));

如德米特里(Dmitry)所建议的那样,最好使用 Linq 方法。

btn_Click 方法上,您犯了同样的错误。 lRes 列表已正确初始化和设置大小,但仍然为空。因此,您必须应用以前看到的相同修复程序:

lRes.Add(new C2(lNumbers);