BjarkeCK
BjarkeCK

Reputation: 5729

Two generic types in a extension method

Right now my code is code looks something like this: (Simplified!)

public static IQueryable<T> ListedProducts<T,V>(this IQueryable<T> collection) 
     where T : ProductCollection<V> 
     where V: Product
{
     return collection.Where(x => x.Listed == true);
}

And to use it i have to define both Types like this:

SomeCollection.ListedProducts<BikeCollection,BikeProduct>()

This is how i would like it to be:

I want to be able to write something lkie this:

public static IQueryable<T> ListedProducts<T<V>>(this IQueryable<T<V>> collection)
     where T : ProductCollection<V>
{
     return collection.Where(x => x.Listed == true);
}

Where i only needed to write:

SomeCollection.ListedProducts()

I think it's possible since "SomeCollection" contains both types for the generic ListedProducts method.


Hope my question is clear enough and there is a solution :)


UPDATE

There seem to be many fustrations on how my code is set up, so here are some of the classes (simplified)

ProductCollection

public class ProductCollection<T> where T : Product
{
    public int Id { get; set; }
    public string CollectionName { get; set; }
    public virtual ICollection<T> Products { get; set; }
    public bool Listed { get; set; }
}

ProductCollection

public class BikeCollection : ProductCollection<BikeProduct>
{
   //Bike specific properties
}

Upvotes: 1

Views: 225

Answers (2)

Guish
Guish

Reputation: 5160

Whould this work?

public static class StaticFunctions
{
    public static IQueryable<ProductCollection<T>> ListedProducts<T>(this IQueryable<ProductCollection<T>> collection)
    where T : Product
    {
        return collection.Where(x => x.Listed == true);
    }
}

public class ProductCollection<T>
    where T:Product
{
    public int Id { get; set; }
    public string CollectionName { get; set; }
    public virtual ICollection<T> Products { get; set; }
    public bool Listed { get; set; }
}

public class BikeCollection : ProductCollection<BikeProduct>
{
    //Bike specific collection
}

public class BikeProduct:Product
{
    //Can be anything
}

public class Product
{
    //Can be anything
}

public partial class Form1 : Form
{


    public Form1()
    {
         InitializeComponent();
         IQueryable<ProductCollection<BikeProduct>> titi = new EnumerableQuery<ProductCollection<BikeProduct>>(new List<ProductCollection<BikeProduct>>());

        titi.ListedProducts();

        var toto = 1;
    }
}

Upvotes: 0

alc
alc

Reputation: 1557

Edit: Based on your recent updates, I'd suggest the following:

Recommendations: change ProductCollection<T> so that it implements IEnumerable<T>:

public class ProductCollection<T> : IEnumerable<T>
  where T : Product
{
  public int Id { get; set; }
  public string CollectionName { get; set; }
  public virtual ICollection<T> Products { get; set; }
  public bool Listed { get; set; }

  // This is all it takes to implement IEnumerable<T>
  public IEnumerator<T> GetEnumerator()   { return this.Products.GetEnumerator(); }
  IEnumerator IEnumerable.GetEnumerator() { return this.Products.GetEnumerator(); }
}

Then, you can change your extension in the following way:

public static IEnumerable<T> ListedProducts<T>(this IEnumerable<T> collection) 
  where T : Product
{
  return collection.Where(x => x.Listed == true);
}

This allows you to do things like:

// WHERE  BikeCollection : ProductCollection<BikeProduct>
// AND    BikeProduct : Product
var someCollection = new BikeCollection();

// What you want
var listedBikes1 = someCollection.ListedProducts();

// Another way you can do it, if ProductCollection<T> : IEnumerable<T>
var listedBikes2 =
  from product in someCollection
  where product.Listed
  select product;

Upvotes: 3

Related Questions