2013-12-21 45 views
5

爲了更多地瞭解Func委託和表達式樹,我將一個簡單的例子放在一起,但是我沒有得到我期望的結果。下面是我的代碼,它有一個Func,它需要一個Params類和一個產品列表。這個想法是將Params類作爲過濾器應用於產品列表。正如我所說,這只是一個練習,讓我學習如何運作。用Func Delegate返回值

我在等待代理返回至少一個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; } 
} 
+1

你的'filterFunc'沒有問題......但是ToList()將返回一個「List 」和「List 」的實例不是'Products'所以'as Products'表達式總是返回'null' ... – nemesv

+0

'List prods = filterFunc(param,products).ToList()'也是空的嗎? –

回答

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對象的集合:Where方法,接受IEnumerable<T>和條件

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

Func您正在使用,然後返回IEnumerable<T>。它將輸入枚舉包裝在另一個枚舉中,這限制了底層枚舉元素的數量,所以返回的對象實現了IEnumerable,但不是輸入對象類型(您的案例中的產品)。

使用as如果無法執行轉換,則運算符爲null。

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(); 

或者可能(如果產品具有接受一個I​​Enumerable構造):

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