【问题标题】:How to Insert an object in a list at custom index如何在自定义索引的列表中插入对象
【发布时间】:2015-12-23 13:54:51
【问题描述】:

我有一个定义为包含 120 个值的空列表,我想在 index(45) 处插入一个元素,即使该列表当前是空的。这可能吗?

public List<Ticket> Tickets = new List<Ticket>(120);

Tickets.Insert(45,ticket); // Here I am getting the ArgumentOutOfRangeException

【问题讨论】:

  • 你想解决什么真正的问题?为什么要在空列表中的特定“索引”处插入项目?为什么不是字典?解决原始问题比尝试更改 List 的行为更容易
  • 使用 Dictionary&lt;int, Ticket&gt; 或自定义容器等其他数据结构会是更好的解决方案吗?

标签: c# .net list object


【解决方案1】:

您将列表的初始内部容量设置为 120。列表仍然是空的。

List&lt;T&gt; 可以容纳任意数量的项目。在内部,它使用一个数组来存储它们。如果数组已满,列表将分配一个新的、更大的。如果事先知道项数,可以在构造列表时设置内部数组的大小。这样可以避免不必要的内存分配。

你可以使用数组:

Ticket[] tickets = new Ticket[120];
tickets[45] = ticket

Dictionary&lt;int, Ticket&gt;

Dictionary<int, Ticket> tickets = new Dictionary<int, Ticket>();
tickets.Add(45, ticket);

或创建一个 List&lt;Ticket&gt; 持有 120 个空值:

List<Ticket> tickets = Enumerable.Repeat(default(Ticket), 120).ToList();

【讨论】:

    【解决方案2】:

    120 被定义为列表的capacity - 而不是真正存在的元素。所以在这种情况下,您的列表在插入时包含 0 个元素。

    当您尝试将位置 45 处的元素插入空列表时 - ArgumentOutOfRangeException 有意义

    【讨论】:

    • 是的,我很清楚这一点,所以我的问题是有什么方法可以做到我想要的吗?向指定索引添加元素?
    • 如何在列表中没有任何元素的情况下添加它们?没有意义。@NaughtyNinja
    • 在做什么?插入第一项时没有索引位置 45。仅当您实际使用 120 个“默认”票证填写列表时,才会存在这种情况。您正在尝试将可变长度集合视为数组或字典(提示)
    • @NaughtyNinja 使用数组代替
    【解决方案3】:

    你也可以使用字典

    var dic = new Dictionary<int,Ticket>();
    dic[45] = ticket;
    

    【讨论】:

      【解决方案4】:

      你应该用一些东西填充列表,因为 List 的这个 ctor 不会填充它。

      public List<Ticket> Tickets =  new List<Ticket>(Enumerable.Repeat (new Ticket(), 120));
      
      Tickets[45] = ticket;
      

      【讨论】:

      • 我感觉数组作为这个用例的数据结构可能更明智。
      【解决方案5】:

      采用int 的构造函数用于定义初始容量,而不是元素的初始数量。

      当您尝试向列表中添加元素时,会运行以下代码:

      private void EnsureCapacity(int min)
      {
        if (this._items.Length >= min)
          return;
        int num = this._items.Length == 0 ? 4 : this._items.Length * 2;
        if ((uint) num > 2146435071U)
          num = 2146435071;
        if (num < min)
          num = min;
        this.Capacity = num;
      }
      

      关键是每次空间不足时,它都会尝试将容量翻倍。这个结果是每次加倍的数组副本。当您知道列表的大小时,为了避免计算成本加倍,请设置初始容量。

      【讨论】:

        【解决方案6】:

        也可以通过数组创建列表,默认初始化所有元素:

        List<Ticket> tickets = new Ticket[120].ToList();
        tickets[45] = ticket;
        

        【讨论】:

          【解决方案7】:
              Dictionary<int, Ticket> Tickets = new Dictionary<int,Ticket>;
              Tickets.Add(45, tickets);
          

          它需要是一个列表吗?顺序重要吗?如果不是,为什么不使用字典或其他键/值对象?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-01-28
            • 2020-08-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多