【问题标题】:How to filter objects based on type-imposed predicate collections?如何根据类型强加的谓词集合过滤对象?
【发布时间】:2020-03-31 19:42:21
【问题描述】:

我有一种情况,我想根据强加于特定类型的谓词集合过滤对象: 这可以通过预编译的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】:

    主要问题是,由于我们要动态选择要调用的谓词,它们需要是Predicate&lt;object&gt; 类型,因为我们调用它们的类型是object。由于Predicate&lt;T&gt;逆变的(定义为Predicate&lt;in T&gt;),这意味着我们可以为T 指定一个派生程度较低的类型,而需要派生更多的类型。

    在实践中,这意味着如果你有一个类 A 和类 B : A,你可以使用 Predicate&lt;A&gt; 作为 Predicate&lt;B&gt;Predicate&lt;object&gt; 作为 Predicate&lt;A&gt;,但你不能这样做Predicate&lt;A&gt; 应该是 Predicate&lt;object&gt;。这意味着您的谓词必须是 Predicate&lt;object&gt; 类型并手动将对象参数转换为正确的类型。

    我想这是一种冗长的说法,你只需要在任何地方使用Predicate&lt;object&gt;,或者找到一些方法来限制你的输入对象。您的MeetsCriteria 方法真的需要处理所有可能存在的对象吗?

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

    【讨论】:

    • 我可以将其限制为类层次结构,但问题是一样的。我有某种类型的对象(可能来自一个共同的父对象),但我需要能够提供基于谓词在派生类型上。
    • 核心问题仍然是你试图在某个东西上调用一个类型化的函数,据 C# 编译器所知,它的类型是object。在调用函数之前它如何知道将其转换为什么类型?您可以尝试通过例如创建一个像PredicateContainer&lt;T&gt; 这样的泛型类来解决这个问题,它可以有一个采用object 参数的方法,检查它是否属于T 类型,如果是,则调用指定的类型化委托。我的观点是,您无法以强类型的方式完成此操作。
    • 但我不希望以强类型的方式完成它。我只是希望以一种有效的方式来完成它,因为对象将从具有高吞吐量的消息队列中到达
    猜你喜欢
    • 2019-10-15
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2020-05-20
    相关资源
    最近更新 更多