In an effort to learn more about Func Delegates and Expression trees, I put together a simple example, however I am not getting the results I expect. Below is my code that has a Func that expects a Params class and a List of Products. The idea is to apply the Params Class as a filter against a list of Products. As I said, this is just an exercise for me to learn how all this works.
I am expecting the delegate to return a least one Product object, however it returns null.
static void Main(string[] args)
{
Products products = CreateProducts();
Params param = new Params { Val = "ABC"};
Func<Params, Products, IEnumerable<Product>> filterFunc =
(p, r) => r.Where(x => x.Sku == p.Val).AsEnumerable();
Products prods = filterFunc(param, products).ToList() as Products;// returns null
}
private static Products CreateProducts()
{
return new Products
{
new Product{
Price = 25.00,
Sku = "ABC"
},
new Product{
Price = 134.00,
Sku = "DEF"
}
};
}
classes:
public class Params
{
public String Val { get; set; }
}
public class Products : List<Product>
{
}
public class Product
{
public String Sku { get; set; }
public double Price { get; set; }
}
The problem is that ToList returns a List<Product>, but that's a distinctly different type than Products. You could provide a constructor of Products which accepts an IEnumerable<Product> like this:
public class Products : List<Product> {
public Products(IEnumerable<Product> products) : base(products) {
}
}
Products prods = new Products(filterFunc(param, products));
But if this is all your Products class does, it's probably a lot simpler to just get rid of it entirely and deal with IEnumerable<Product> (or List<Product>) wherever you need to handle a collection of Product objects:
IEnumerable<Product> products = CreateProducts();
Params param = new Params { Val = "ABC"};
Func<Params, IEnumerable<Product>, IEnumerable<Product>> filterFunc =
(p, r) => r.Where(x => x.Sku == p.Val);
IEnumerable<Product> prods = filterFunc(param, products);
private static IEnumerable<Product> CreateProducts()
{
return new Products[] {
new Product{
Price = 25.00,
Sku = "ABC"
},
new Product{
Price = 134.00,
Sku = "DEF"
},
};
}
Your call to .ToList() will return a List<Product>, not a Products (whatever that is), thus the call to as Products will fail its cast and will return null.
Products prods = filterFunc(param, products).ToList() as Products;// returns null
This might work (depending on the definition of Products which you haven't supplied:
List<Product> prods = filterFunc(param, products).ToList();
Or possibly (if products has a constructor that accepts an IEnumerable):
Products prods = new Products(filterFunc(param, products));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With