2012-06-14 21 views
6

私は、オブジェクトのリストに適用するフィルタのリストを動的に構築する必要がある状況があります。これらのオブジェクトは、フィルタリングする必要があるすべてのプロパティを含むインタフェースを実装するものであれば何でもかまいません。私はその後、基準を適用し、私はそう...C#総称制約が期待通りに機能しない

public List<Expression<Func<IStuff, bool>>> Criteria { get; private set; } 

などのような条件を追加するように定義された基準のリストを持っている

public interface IStuff 
{ 
    bool SuitableForSomething { get; set; } 
    bool SuitableForSomethingElse { get; set; } 
} 

public class SomeStuff : IStuff 
{ 
    ... 
} 

public class SomeOtherStuff : IStuff 
{ 
    ... 
} 

...

Criteria.Add(x => x.SuitableForSomething); 
Criteria.Add(x => x.SuitableForSomethingElse); 

ように私のクエリに...

01以下の拡張メソッドを使用しています
var stuff= _stuffCache 
    .GetAll() 
    .AsQueryable() 
    .ApplyCriteria(Criteria); 

...

public static IQueryable<T> ApplyCriteria<T>(this IQueryable<T> stuff, List<Expression<Func<IStuff, bool>>> criteria) 
    where T : IStuff 
{ 
    foreach (var expression in criteria) 
    { 
     stuff = Queryable.Where(stuff, expression); 
    } 
    return stuff; 
} 

私はエラーの下に赤い線の上に置くと、コンパイラは

...

cannot convert from 
    'System.Linq.Expressions.Expression<System.Func<IStuff,bool>>' 
to 
    'System.Linq.Expressions.Expression<System.Func<T,int,bool>>' 
を私に言っていますIDEはメソッドを解決できないと言っています

IQueryable<IStuff> Where<IStuff>(this IQueryable<IStuff>, Expression<Func<IStuff, bool>>) in class Queryable 
and 
    IQueryable<T> Where<T>(this IQueryable<T>, Expression<Func<T,int,bool>>) in class Queryable 

式をExpression<Func<T, bool>>にキャストしようとすると、TがIStuffインターフェイスを実装するように制約されているため、動作するはずです。私は

Cannot cast expression of type 'Expression<Func<IStuff, bool>>' to type 'Expression<Func<T, bool>>' 

EDIT おかげで私は、コードを呼んでいたとき、鋳造問題だった私が持っていた本当の問題は、見つけ最終的に拡張メソッドを固定し、Raphaëlの答えに着きます。 ApplyCriteriaコールの後に.Cast<SomeStuff>()を追加すると簡単に修正されました。

var stuff= _stuffCache 
    .GetAll() 
    .AsQueryable() 
    .ApplyCriteria(Criteria); 

var stuff= _stuffCache 
    .GetAll() 
    .AsQueryable() 
    .ApplyCriteria(Criteria) 
    .Cast<SomeStuff>(); 

答えて

7

変更第2のパラメータのタイプへ

public static IQueryable<T> ApplyCriteria<T>(this IQueryable<T> stuff, List<Expression<Func<T, bool>>> criteria) 
    where T : IStuff 
{ 
    foreach (var expression in criteria) 
    { 
     stuff = Queryable.Where(stuff, expression); 
     //or stuff = stuff.Where(expression), as Where is an Extension method; 
    } 
    return stuff; 
} 

(T代わりIStuffの)List<Expression<Func<T,bool>>>とあなたの方法があることができる(THXレシャール)、書き直して

public static IQueryable<T> ApplyCriteria<T>(this IQueryable<T> stuff, List<Expression<Func<T, bool>>> criteria) 
      where T : IStuff 
     { 
      return criteria.Aggregate(stuff, (current, expression) => current.Where(expression)); 
     } 
+0

改善提案と虚偽+1があります。ありがとう。 – SimpleVar

+0

私はすでにそれを試していましたが、他のエラーがありました。私は詳細で質問を更新します。 –

関連する問題