2011-08-12 8 views
0

メソッド内のLINQクエリで使用される「場所」ラムダ式を渡す必要があります。問題は、メソッドに入るまで、どこの値を比較するのか分かりません。ラムダ式をビルドしてメソッドに渡す

ここでさらに説明し、私が上で述べたことのいくつかを明確にするために、私は少しの人為的な例を考え出します。

私はがあり、ProductsオブジェクトのproductIdプロパティを使用してそのリストを1つのレコードに絞り込む必要があるとします。私はList<Products>に限定されず、代わりにとても理想的List<T>ですされていないメソッドに上記のロジックを配置する必要があり、私はなるだろう -

var product = productList.Where(p=>p.productId == 123).FirstOrDefault(); 

今さらに一歩それを取る:通常私はこれを行うだろうこのようにそれを呼び出す(と私は以下の動作しません知っている、それは私が達成しようとしているかを示すために、ここで簡単にです):

myMethod(productList, p => p.productId == X) 

注意点はXが知られていないことをされた状態で私はまでメソッド内。

最後に、私のデータのコレクションがOData DataServiceQueryであることを指摘する必要があります。

私の質問を再要約するには:メソッドに渡すことができるラムダ "where"式を構築する方法と、LINQクエリのオブジェクトのコレクションに対してこのメ​​ソッドを使用する方法を知る必要があります。

+0

Tは常にproductIdプロパティを持っていますか? – sll

+0

いいえ、productIdは必ずしもプロパティではありません。時々私はユーザーのリストを持っているかもしれないので、それはUserId、あるいはCompanyオブジェクトのセットのcompanyIdでしょう。 – bugfixr

答えて

2

MyMethodは(productList、P => p.productId == X) - あなたはこのトリック

static void myMethod<T>(List<T> list, Func<T,bool> predicate, ref int x) 
    { 
     x = 5; 
     var v = list.Where(predicate); 
     foreach (var i in v) 
      Console.Write(i); 
     Console.ReadLine(); 
    } 

    static void Main(string[] args) 
    { 
     List<int> x = new List<int> { 1, 2, 3, 4, 5 }; 
     int z = 0; 
     myMethod(x, p => p == z, ref z); 
    } 

ではなく、それは全体

+0

面白いアイデア!これがどこかで実装されているのを見たら、それをハックと見なしますか? – bugfixr

+0

これは実装されていませんが、ハックではありません。文法の観点からはかなり合法です。 – elevener

0

であなたの問題を解決するかどうかあなたがに試みることができることを確認してエミュレートすることができます無料のLinqKitライブラリ(tutorial)のPredicateBuilderクラスを使用してください。

あなたは、あなたがそのような.Where(predicate)としてwhere句は、この述部を使用してのIQueryableを返すか、述語自体を返すことができ、Xは、型Tの

ある

PredicateBuilder predicate = PredicateBuilder.True<T>(); 
predicate = PredicateBuilder.And(predicate, p=> p.product_id == X); 

を使用して述語を構築することができますタイプがExpression<Func<T, bool>>

2

IEnumerable<T>を照会する場合は、最初に比較が行われるようにする必要があります。その場合、オブジェクトが比較をサポートすることを保証するインタフェースを実装することができます。

これを実行すると、メソッドには、入力をこれらのインターフェイスに制限するジェネリック制約が設定されます。私は上記の修正 :

var match = GetMatch<Identifier>(collection, (x, y) => x.Id == y); 

UPDATE:よう

public interface Identifier 
{ 
    int Id { get; set; } 
} 

public class Product : Identifier 
{ 
    public int Id { get; set; } 
    //Other stuff 
} 

public T GetMatch<T>(IEnumerable<T> collection, Func<T, int, bool> predicate) where T : Identifier 
{ 
    int comparison = 5; 
    return collection.Where(item => predicate(item, comparison)).FirstOrDefault(); 
} 

呼び出すことができます。その時点で、あなたの方法は、句LINQに渡すことができるのFuncを取ることができます比較パラメータを取るコード

+0

ありがとうございました。主な問題は、メソッドが実行されるまで5の値がわからないことです。 – bugfixr

+0

@Chu - GetSubcollection メソッドのパラメータとして渡される値(この例では5)ですか?値はどのように関数スコープの内部に入りますか? – davecoulter

+0

@Chu - Func <> – davecoulter