tags:

views:

979

answers:

2

I often find linq being problematic when working with custom collection object. They are often defened as

The base collection

abstract class BaseCollection<T> : List<T> { ... }

the collections is defined as

class PruductCollection : BaseCollection<Product> { ... }

Is there a better way to add results from a linq expession to this collection than addrange or concat?

var products = from p in HugeProductCollection
               where p.Vendor = currentVendor
               select p;
PruductCollection objVendorProducts = new PruductCollection();
objVendorProducts.AddRange(products);

It would be nice if the object returned form the linq query was of my custom collection type. As you seem to need to enumerate the collection two times to do this.

EDIT : After reading the answers i think the best solution is to implementa a ToProduct() extention. Wonder if the covariance/contravariance in c#4.0 will help solve these kinds of problems.

+2  A: 

The problem is that LINQ, through extension methods on IEnumerable<T>, knows how to build Arrays, Lists, and Dictionaries, it doesn't know how to build your custom collection. You could have your custom collection have a constructor that takes an IEnumerable<T> or you could write you. The former would allow you to use the LINQ result in your constructor directly, the latter would allow you to decorate the LINQ statement with your extension and get back the collection you desire. Either way you'll need to do some sort of conversion from the generic collection to your specialized collection -- either in the constructor or in the extension. Or you could do both...

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();
tvanfosson
+2  A: 

I can suggest you a way in that you don't have to enumerate the collection 2 times:

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);
bruno conde
+1 for your answer
Krunal