2013-12-21 7 views
5

Funcデリゲートとエクスプレッションツリーの詳細については、簡単な例を示しますが、期待した結果が得られません。以下は、ParamsクラスとList of Productsが必要なFuncを持つコードです。この考え方は、Paramsクラスを製品のリストに対するフィルタとして適用することです。私が言ったように、これは私がこのすべての仕組みを学ぶための運動です。Funcデリゲートを使用した値の返却

デリゲートが少なくとも1つの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()'もnullですか? –

答えて

7

問題はToListList<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クラスがない場合は、それだけで完全にそれを取り除くと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

FuncであなたはIEnumerable<T>を返し、その後、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(); 

または可能性を(製品はIEnumerableをを受け取るコンストラクタを持っている場合:

Products prods = new Products(filterFunc(param, products)); 
関連する問題