我有一种情况,我想根据施加在其特定类型上的谓词集合来过滤对象:可以通过预编译的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;
}
主要问题是,由于我们要动态选择要调用的谓词,因此谓词必须为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是否需要处理可能存在的每个对象?
我不相信您的要求可以用表达式树来解决,因为类型问题仍然存在,但是,也许有人会证明我错了。