如何迭代子类中的 List<T> 基类?

Posted

技术标签:

【中文标题】如何迭代子类中的 List<T> 基类?【英文标题】:How to iterates over a List<T> base class within the child class? 【发布时间】:2021-05-27 15:05:22 【问题描述】:

我有一个继承 List 的集合类。我想要该类上的一个方法,它可以遍历基类列表中的项目。

目前我有这个:

    public class Invoices : List<Invoice>
    
        public string ToString()
        
            string cOP = "";
            int i;
            Invoice oInvoice;

            cOP += string.Format("Invoices.Count = 0\r\n", base.Count);

            foreach (Invoice oInvoice in base)
            
                cOP += oInvoice.ToString();
            

            return cOP;
        
    

但是我在 foreach 语句中的 base 上得到了编译时错误,“Use of keyword 'base' is not valid in this context”。

我尝试将 base 替换为:

base.ToArray() - 这确实有效,但我认为 List 的全部意义在于它是可枚举的。 base.ToList() - “'System.Collections.Generic.List' 不包含 'ToList' 的定义”

我是否需要将 List 转换为 Array 以对其进行迭代?当然我应该能够迭代列表吗?

【问题讨论】:

这里有一个提示,从List&lt;T&gt; 继承是一种不好的做法。 使用this 代替base? (注意:MS 指南说你应该继承自 Collection&lt;T&gt; 而不是 List&lt;T&gt; Why not inherit from List<T>? 用 Eric Lipperts 的话来说:“你想扩展 List 机制还是想创建一个需要集合的业务对象”?我确定你想要后者,所以让它成为你班级的一个属性。 蒂姆是绝对正确的——你应该prefer composition over inheritance 【参考方案1】:

这是一种更常用的方法

public class Invoices : IEnumerable<Invoice>

   private readonly List<Invoice> _invoices = new List<Invoice>();

   public IEnumerator<Invoice> GetEnumerator() => _invoices.GetEnumerator(); 
   IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

   public override string ToString()
   
      var sb = new StringBuilder();

      sb.AppendLine($"Invoices.Count = _invoices.Count");

      foreach (var oInvoice in _invoices)
         sb.Append(oInvoice);

      return sb.ToString();
     

只需添加您需要的方法。如果需要更多列表类型方法,实现ICollectionIList

【讨论】:

谢谢,伙计,您让我搜索继承列表的性能/设计注意事项。我主要发现它是一个设计问题,而不是性能问题。 ***.com/questions/21692193/why-not-inherit-from-listt 无论如何,非常感谢。【参考方案2】:

您应该使用this 关键字:

public class Invoices : List<Invoice>

    public string ToString()
    
        string cOP = "";
        int i;
        Invoice oInvoice;

        cOP += string.Format("Invoices.Count = 0\r\n", base.Count);

        foreach (Invoice oInvoice in this)
        
            cOP += oInvoice.ToString();
        

        return cOP;
    

【讨论】:

虽然这个答案会起作用,但请注意继承 List&lt;T&gt; 并不是最好的主意。 对于未来的读者来说,虽然这解决了问题,但这不是合适的解决方案。请阅读问题下的cmets 谢谢两位。我不知道继承 List 是一个糟糕的设计。上面的类只是一个测试项目的一部分,用于试验序列化,所以没有造成重大伤害。我会记住这一点的。感谢您的帮助。

以上是关于如何迭代子类中的 List<T> 基类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在基类中实现子类迭代器的统一接口?

在 std::vector<T> 和 std::vector<unique_ptr<T>> 上均匀迭代

JAVA集合02_List集合的概述并发修改异常迭代器遍历子类对比

C++获取基类指针所指子类对象的类名

将变量作为基类对象迭代,同时转换为子类并在 C++ 中使用它们的覆盖方法

JAVA List<T> 如何初始化