为了更多地了解Func Delegates和Expression树,我把一个简单的例子放在一起,但是我没有得到我期望的结果。下面是我的代码,它有一个Func,需要一个Params类和一个产品列表。我们的想法是将Params类应用为针对产品列表的过滤器。正如我所说,这只是我练习如何运作的练习。
我希望委托返回至少一个Product对象,但是它返回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"
}
};
}
类:
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; }
}
答案 0 :(得分:7)
问题是ToList
会返回List<Product>
,但这与Products
的类型明显不同。您可以提供Products
的构造函数,该构造函数接受IEnumerable<Product>
,如下所示:
public class Products : List<Product> {
public Products(IEnumerable<Product> products) : base(products) {
}
}
Products prods = new Products(filterFunc(param, products));
但是,如果这是你所有的Products
类,那么完全摆脱它并在需要处理的任何地方处理IEnumerable<Product>
(或List<Product>
)可能要简单得多Product
个对象的集合:
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"
},
};
}
答案 1 :(得分:2)
您对.ToList()
的来电将返回List<Product>
,而不是Products
(无论是什么),因此对as Products
的调用将失败,并将返回{ {1}}。
null
这可能有效(取决于您未提供的Products prods = filterFunc(param, products).ToList() as Products;// returns null
的定义:
Products
或者可能(如果产品有一个接受IEnumerable的构造函数):
List<Product> prods = filterFunc(param, products).ToList();
答案 2 :(得分:-1)
在Func
你正在使用Where方法,接受IEnumerable<T>
和条件,然后返回IEnumerable<T>
。它将可枚举的输入包装在另一个可枚举内,这限制了底层可枚举元素的数量,因此返回的对象实现IEnumerable但不是输入对象的类型(在您的情况下为Products)。
如果无法执行强制转换,则使用as
运算符会返回null。