Linq与自定义基础集合
在使用自定义集合对象时,我经常发现linq存在问题。 他们经常被打败
基础集合
abstract class BaseCollection : List { ... }
集合定义为
class PruductCollection : BaseCollection { ... }
是否有更好的方法将linq exssion的结果添加到此集合中,而不是addrange或concat?
var products = from p in HugeProductCollection where p.Vendor = currentVendor select p; PruductCollection objVendorProducts = new PruductCollection(); objVendorProducts.AddRange(products);
如果从linq查询返回的对象属于我的自定义集合类型,那将是很好的。 因为您似乎需要两次枚举该集合才能执行此操作。
编辑 :阅读答案后,我认为最好的解决方案是实现ToProduct()扩展。 不知道c#4.0中的协方差/逆变是否有助于解决这些问题。
问题是LINQ通过IEnumerable
上的扩展方法知道如何构建Arrays,Lists和Dictionaries,它不知道如何构建自定义集合。 你可以让你的自定义集合有一个构造函数,它接受一个IEnumerable
或者你可以写你。 前者允许您直接在构造函数中使用LINQ结果,后者允许您使用扩展来装饰LINQ语句并获取所需的集合。 无论哪种方式,您都需要从generics集合到专用集合进行某种转换 – 无论是在构造函数中还是在扩展中。 或者你可以做到两个……
public static class MyExtensions { public static ProductCollection ToProducts( this IEnumerable collection ) { return new ProductCollection( collection ); } } public class ProductCollection : BaseCollection { ... public ProductCollection( IEnumerable collection ) : base( collection ) { } ... } var products = (from p in HugeProductCollection where p.Vendor = currentVendor select p).ToProducts();
我可以建议你一个方法,你不必枚举2次集合:
abstract class BaseCollection : List { public BaseCollection(IEnumerable collection) : base(collection) { } } class PruductCollection : BaseCollection { public PruductCollection(IEnumerable collection) : base(collection) { } } var products = from p in HugeProductCollection where p.Vendor = currentVendor select p; PruductCollection objVendorProducts = new PruductCollection(products);
这可以使用BindingList吗? 因为BindingList没有构造函数,它将采用IEnumerable但实现它。
BindingList:Collection,IBindingList,IList,ICollection,IEnumerable,ICancelAddNew,IRaiseItemChangedEvents