在下列集合:
public class PersonsCollection : List<Person>
如何通过Where
扩展过滤后返回PersonsCollection
的实例?
personCollections.Where(p => p.Name == "Jack").ToList();
// will return IEnumerable<Person>, How to return PersonsCollection?
任何想法!
您必须创建一个新的PersonsCollection
实例,例如
return new PersonsCollection(personsCollection.Where(p => p.Name == "Jack"))
假设你有一个合适的构造函数。
一般来说,扩展内置集合(而不是使用组合)是一个坏主意——你确定你想要这种设计吗?
您可以为IEnumerable<Person>
创建一个扩展方法ToList()
…
public static class PersonCollectionExtensions
{
public static List<Person> ToList(this IEnumerable<Person> self)
{
return new PersonCollection(self);
}
}
像这样:
var pc = new PersonCollection();
pc.AddRange(personCollections.Where(p => p.Name == "Jack").ToArray());
return pc;
几种可能性:
-
你的PersonsCollection有一个接受
IEnumerable<Person>
的构造函数,所以你可以根据查询结果创建一个新的PersonsCollection -
您可以创建一个新的扩展方法ToPersonsCollection()来构造PersonsCollection(可以与上面的方法结合使用)
-
你可以改变你的依赖,使其他代码不需要一个PersonsCollection,可以代替
IEnumerable<Person>
工作(这是我推荐的选项)
您需要在集合中创建适当的构造函数:
public class PersonsCollection : List<Person> {
public PersonsCollection() { }
public PersonsCollection(IEnumerable<Person> persons) : base(persons) { }
}
你可以这样过滤:
new PersonsCollection(personCollections.Where(p => p.Name == "Jack"));
从你对CollectionBase
的评论来看,我猜你是在重构旧代码,而不是使用泛型。Krzysztof Cwalina写了一篇关于如何从非泛型集合过渡到泛型集合的博文。您可能还会发现他在一篇博客文章中对为什么不推荐在公共API中使用List<T>
的评论很有趣:
我们建议使用
Collection<T>
、ReadOnlyCollection<T>
或KeyedCollection<TKey,TItem>
作为输出和属性,使用IEnumerable<T>
、ICollection<T>
、IList<T>
作为输入接口。
你可以简单地去掉PersonsCollection
,用Collection<Person>
代替。