如何基于类型强加的谓词集合过滤对象?

问题描述 投票:2回答:1

我有一种情况,我想根据施加在其特定类型上的谓词集合来过滤对象:可以通过预编译的ExpressionTrees完成吗?

class A
{
   public int Value {get;set;}
}
class B
{
  public string Name {get;set;}
  public bool IsMajor{get;set;}
}


Dictionary<Type,IEnumerable<Predicate<[object casted to type]>> typePredicateMap=new Dictionary<Type,Predicate<[object casted to type]>>{
   {typeof(A),new List<Predicate<[object casted to A]> { x=>x.Value >100,x=>x.Value<200 }},
   {typeof(B),new List<Predicate<[object casted to B]> { x=>x.Name!="johhnny",x=>x.IsMajor==true }}
}

我在object casted to Type之前说过,因为我希望我的谓词基于该特定类型。

public static bool MeetsCriteria(object data)
{
    Type type=typeof(data);
    IEnumerable<Predicate<object>predicates=typePredicateMap[type];
    bool isValid=true;
    foreach(var predicate in predicates)
    {
        isValid&=predicate(data);  //
    }
    return isValid;
}
c# expression-trees predicate
1个回答
2
投票

主要问题是,由于我们要动态选择要调用的谓词,因此谓词必须为Predicate<object>类型,因为我们要调用它们的类型为object。由于Predicate<T>contravariant(定义为Predicate<in T>),这意味着我们可以为T指定一个较少派生的类型,而期望更多派生的类型。

实际上,这意味着如果您具有A类和B : A类,则可以将Predicate<A>用作Predicate<B>或将Predicate<object>用作Predicate<A>,但不能执行[ C0],其中应为Predicate<A>。这意味着您的谓词必须为Predicate<object>类型,并手动将object参数转换为正确的类型。

我想这是一个漫长的说法,您只需要在各处使用Predicate<object>,或者找到某种方式来约束您的输入对象。您的Predicate<object>方法really是否需要处理可能存在的每个对象?

我不相信您的要求可以用表达式树来解决,因为类型问题仍然存在,但是,也许有人会证明我错了。

© www.soinside.com 2019 - 2024. All rights reserved.