使用Func委托返回值

5
为了更多地了解Func Delegates和Expression trees,我制作了一个简单的示例,但是我没有得到我期望的结果。以下是我的代码,其中有一个期望Params类和产品列表的Func。想法是将Params类应用为筛选器来筛选产品列表。就像我说的,这只是一个练习,让我了解所有这些都是如何工作的。
我希望委托能够返回至少一个产品对象,但它返回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; }
}

1
你的 filterFunc 没有问题... 但是 ToList() 将返回一个 List<Product> 实例,而 List<Product> 不是与 Products 相同的类型,因此 as Products 表达式总是返回 null... - nemesv
List<Product> prods = filterFunc(param, products).ToList() 是否也为 null? - Konrad Kokosa
3个回答

7
问题在于ToList返回一个List<Product>,但这是与Products明显不同的类型。您可以提供一个接受IEnumerable<Product>Products构造函数,如下所示:
public class Products : List<Product> {
    public Products(IEnumerable<Product> products) : base(products) {
    }
}

Products prods = new Products(filterFunc(param, products));

但如果你的 Products 类只是做这些事情,那么完全可以将其删除,并在需要处理 Product 对象集合时使用 IEnumerable<Product> (或 List<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"
        },
    };
}

2

你调用 .ToList() 方法会返回一个 List<Product>,而不是一个 Products(不知道这是什么),因此调用 as Products 会失败并返回 null

Products prods = filterFunc(param, products).ToList() as Products;// returns null

这可能有效(取决于您未提供的Products的定义):
List<Product> prods = filterFunc(param, products).ToList();

或者(如果产品具有接受 IEnumerable 的构造函数):
Products prods = new Products(filterFunc(param, products));

-1
Func 中,您正在使用接受 IEnumerable<T> 和条件的 Where 方法,然后返回 IEnumerable<T> 的方法。它将输入可枚举对象包装在另一个可枚举对象中,该对象限制基础可枚举对象的元素数量,因此返回的对象实现了 IEnumerable,但不是输入对象(在您的情况下为 Products)的类型。
使用 as 运算符在无法执行转换时返回 null。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接