2012-06-14 31 views
6

Nesnelerin listesine uygulamak için dinamik olarak bir filtre listesi oluşturmam gereken bir durum var. Bu nesneler, filtrelemek için ihtiyacım olan tüm özellikleri içeren bir arabirimi uygulayan her şey olabilir.C# generic kısıtı beklendiği gibi çalışmıyor

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

public class SomeStuff : IStuff 
{ 
    ... 
} 

public class SomeOtherStuff : IStuff 
{ 
    ... 
} 

Ben

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

Sonra kuralları uygulamak ... ...

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

şöyle tanımlanmış kriterler listesi var ve bu yüzden gibi ölçüt eklemek benim sorguya kadar ...

Şu uzantı yöntemini kullanır
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; 
} 

derleyici beni anlatıyor ...

Yanlışlıkla altında kırmızı çizgi üzerinde gezdirin
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 
arasındaki yöntemi çözemediğini söylüyor

İfadeyi Expression<Func<T, bool>>'a çevirmeye çalışırsam, bu, T, IStuff arabirimini uygulamak için kısıtlı olduğu için çalışmalıdır. Ben

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

DÜZENLEME teşekkürler ben kod çağırıyordu zaman döküm sorunu oldu ben gerçek bir sorun, buldum sonunda uzatma yöntemi sabit ve Raphaël 'ın cevabı olsun. ApplyCriteria çağrısından sonra .Cast<SomeStuff>() ekleyerek kolayca sabitlenir.

önce

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

sonra

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

cevap

7

değişiklik, ikinci parametre tipi

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 yerine IStuff arasında) List<Expression<Func<T,bool>>> ve yöntem olabilir (thx reshar Her bir düzeltme için doğru cevap ve hayali +1 için

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'e yeniden yazılmıştır. – SimpleVar

+0

teşekkürler. Bunu zaten denedim ve şimdi bir çözüm bulmuş olduğum diğer hataları aldım. Soruyu ayrıntılarla güncelleyeceğim. –

İlgili konular