2010-12-26 4 views
0

私は2つの述部の平等を決定しようとしている:C#の述語パラメータ内の値を調べる方法は? - 決定述語の平等

public T FirstOrDefault(Func<T, bool> predicate) 
{ 
    if (EntityCache.ContainsKey(predicate.GetHashCode())) 
     return EntityCache[predicate.GetHashCode()]; 
    else 
    { 
     var entity = _objectSet.FirstOrDefault<T>(predicate); 
     EntityCache.Add(predicate.GetHashCode(), entity); 
     return entity; 
    } 
} 

私がいる問題は、その中に使用される値を考慮していない述語のハッシュコードであり、私はそれらを取得する方法についてはわかりません。

たとえば、上記のメソッドに渡された述語は、(r => r.Id == id)私のFirstOrDefaultメソッド内で 'id'の値を見つける方法は?

+0

を使用する方が良いだろうことに注意して維持されますに? 'Func 'を取り上げる構文の全体は、どのように実装されているか分かりません。メソッドの* user *がどのように結果をフィルタリングするかを知ることは、FirstOrDefaultの* implementor *としてあなた次第ではありません。彼らは 'Id'プロパティを使うことを選ぶかもしれませんし、まったく異なる述語を持つかもしれません。値が分かれば、 'Func 'を取り込み、それらがpkを返すと仮定し、述語を呼び出して 'T'の現在のインスタンスの値を得ることができます。 –

+0

私は、述語を渡す柔軟性を保ちたいし、何らかの形でその述語と値のセットが前に渡されたものと同じかどうかを判断できるので、これを行う簡単な方法はないと思います。 – BrooklynDev

答えて

0

エクスプレッションを使用する必要があります。それらにはfuncが含まれていますが、構文ツリーも含まれており、実行時に 'ソースコード'を調べることができます。

+0

しかし、私は物事を行うこの方法はまだ臭い、あなたも述語をキャッシュしてはならないことを認めなければなりません。たとえば、フィールド名とフィールド値をカプセル化する独自のクラスを作成します。新しいQueryFilter( "Id"、12)と同様です。これにより、はるかに優れたデザインにつながります。 – fejesjoco

+0

私は、メソッドに必要な述語を渡すことができる柔軟性を維持したいと思いますが、その述語とそれが以前に渡されたパラメータ値かどうかを何らかの形で判断したいだけです。 – BrooklynDev

+0

私の提案はあなたを限定するものではなく、フィルター表現の派生物のセットを作成することができます。 param型がの抽象フィルタ基本クラスを作成します。このクラスには、bool DoesItMatch(T elem)という単一のメソッドがあります。次に、コンストラクタパラメータとしてプロパティ名と値をとるSimpleFilterExpression を取得します。その後、他の派生クラスを自由に追加してください。次に、すべてのクラスがGetHashCodeとEqualsを提供することを確認します。これらの単純な実装クラスがあるため、非常に簡単です。 – fejesjoco

0

あなたが正しく理解している場合、デリゲート内のキャプチャされた変数の値を決定しようとしています。私はこれを行う簡単な方法はないと確信しています...おそらく、より単純な代理人の代わりに式ツリーを使用したのですか? 別のオプション(おそらくずっと簡単)EntityCache

でそれらと並んで代表者に渡された値はまた、あなたが望むのはなぜ代わりに

if (EntityCache.ContainsKey(predicate.GetHashCode())) 
    return EntityCache[predicate.GetHashCode()]; 

TryGetValue

+0

TryGetValueのチップをありがとう、それを使用します。 – BrooklynDev

+0

能ノ、-1。ハッシュコードが(ハトホールの原理) – erikkallen

+0

@erikkallenなので、2つのオブジェクトが等しいことを前提としないでください(ハッシュコードを使用していたことに気づいていませんでした)。答え?私は単に 'contains contains return []'パターンが 'TryGetValue'メソッドでよりうまく実装されていることを指摘していました - そして、それは私の答えの本質を除いていました... –