在使用自定义集合对象时,我经常发现linq存在问题。 他们经常被视为
基础集合
abstract class BaseCollection<T> : List<T> { ... }
集合定义为
class PruductCollection : BaseCollection<Product> { ... }
有没有更好的方法将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中的协方差/逆变是否有助于解决这些问题。
答案 0 :(得分:7)
问题是LINQ通过IEnumerable<T>
上的扩展方法知道如何构建数组,列表和字典,它不知道如何构建自定义集合。你可以让你的自定义集合有一个构造函数,它可以使用IEnumerable<T>
或者你可以写你。前者允许您直接在构造函数中使用LINQ结果,后者允许您使用扩展来装饰LINQ语句并获取所需的集合。无论哪种方式,您都需要从泛型集合到专用集合进行某种转换 - 无论是在构造函数中还是在扩展中。或者你可以做到两个......
public static class MyExtensions
{
public static ProductCollection
ToProducts( this IEnumerable<Product> collection )
{
return new ProductCollection( collection );
}
}
public class ProductCollection : BaseCollection<Product>
{
...
public ProductCollection( IEnumerable<Product> collection )
: base( collection )
{
}
...
}
var products = (from p in HugeProductCollection
where p.Vendor = currentVendor
select p).ToProducts();
答案 1 :(得分:2)
我可以建议你一个方法,你不必两次枚举该集合:
abstract class BaseCollection<T> : List<T>
{
public BaseCollection(IEnumerable<T> collection)
: base(collection)
{
}
}
class PruductCollection : BaseCollection<Product>
{
public PruductCollection(IEnumerable<Product> collection)
: base(collection)
{
}
}
var products = from p in HugeProductCollection
where p.Vendor = currentVendor
select p;
PruductCollection objVendorProducts = new PruductCollection(products);
答案 2 :(得分:-1)
这可以使用BindingList吗?因为BindingList没有构造函数,它将采用IEnumerable但实现它。
BindingList:Collection,IBindingList,IList,ICollection,IEnumerable,ICancelAddNew,IRaiseItemChangedEvents