使用Func委托返回值

时间:2013-12-21 15:30:26

标签: c# linq delegates func

为了更多地了解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; }
}

3 个答案:

答案 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。