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