【问题标题】:Create new derived-class object from List.FindAll从 List.FindAll 创建新的派生类对象
【发布时间】:2020-02-19 12:43:16
【问题描述】:

我有一个名为Myitem 的类和一个派生的ListMyItemCollection...

public class MyItemCollection : List<MyItem> { ... }
public class MyItem { ... }

我想使用 FindAll 返回包含 MyItem 值子集的 MyItemCollection 类的新实例...

public MyItemCollection GetInUse()
{
  return this.FindAll(x => x.InUse);
}

但是,由于FindAll 返回List&lt;MyItem&gt; 而不是MyItemCollection,上述失败。

是否可以让.FindAll返回MyItemsCollection对象,或者使用.FindAll的返回来启动MyItemsCollection对象?

我可以执行以下操作,但我想知道是否有更好的解决方案...

public MyItemCollection GetInUse(bool inUse)
{
  var col = new MyItemsCollection();
  foreach (var item in this.FindAll(x => x.InUse))
    col.Add(item);
  return col;
}

【问题讨论】:

  • 添加带有IEnumerable参数的构造函数。
  • 你几乎从不想要从List&lt;T&gt;派生,因为你也会暴露整个列表接口(添加、删除、基于索引的访问......)。而只是使用它,例如作为实例字段。
  • @Sinatr - 是的,我确实考虑过这一点,但是我仍然需要在构造函数中有一个 foreach 循环......所以看起来几乎毫无意义
  • @freefaller 不,List&lt;T&gt; 已经有一个“复制构造函数”,所以只需使用它,例如public MyItemCollection(IEnumerable&lt;MyItem&gt; collection) : base(collection) { // do whatever else you need to.. }
  • @freefaller 我也会听从 HimBromBeere 的建议; List&lt;T&gt;;通过组合更好地使用,因为实现List&lt;T&gt; 为消费者提供了很多的行为。如果您追求 LINQ 行为,您始终可以实现 IEnumerable&lt;T&gt;

标签: c# lambda generic-list


【解决方案1】:

List&lt;T&gt; 有一个带有IEnumerable&lt;T&gt; 参数的构造函数。您可以在您的类中公开一个类似的构造函数,然后执行以下操作:

public MyItemCollection GetInUse() => new MyItemCollection(this.Where(i => i.InUse));

或者,不要使用您自己的收藏。如果您只想在列表中添加辅助方法,可以使用扩展方法:

public static IEnumerable<MyItem> GetInUse(this IEnumerable<MyItem> e) 
  => e.Where(i => i.InUse);

您还可以通过接口设计您的类以具有这些扩展帮助器。如果您有多个具有相似功能的不相关类,这将很方便。然后扩展方法可以使用该接口作为IEnumerable 的类型参数,或者是具有泛型约束的泛型自身。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-10
    • 2017-02-26
    • 1970-01-01
    • 2020-08-06
    • 2020-03-17
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多