我有一种情况,我想根据对特定类型施加的谓词集合来过滤对象:
这可以通过预编译的 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 }}
}
我上面说过对象转换为类型
,因为我希望我的谓词基于该特定类型..
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>
是逆变的(定义为 Predicate<in T>
),这意味着我们可以为 T 指定一个派生程度较低的类型,而需要派生程度较高的类型。
实际上,这意味着如果您上了一个类 A
和类(class)B : A
,您可以使用 Predicate<A>
作为Predicate<B>
或Predicate<object>
如Predicate<A>
,但你不能这样做Predicate<A>
哪里Predicate<object>
是期待。这意味着您的谓词必须是 Predicate<object>
类型。并手动将对象参数转换为正确的类型。
我想这是一种冗长的说法,你只需要使用Predicate<object>
无处不在,或者找到某种方法来约束您的输入对象。你的MeetsCriteria
吗?方法真的需要处理可能存在的每个对象吗?
我不相信你所要求的问题可以用表达式树来解决,因为类型问题仍然存在,但是嘿,也许有人会证明我错了。
关于c# - 如何根据类型强加的谓词集合过滤对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59219477/