LINQ -使用谓词< >调用过滤器

本文关键字:调用 过滤器 谓词 LINQ | 更新日期: 2023-09-27 18:18:41

我想在我的一个类中提供一种过滤某些元素的方法。为了保持我的界面尽可能的干净和自解释,我希望我的过滤器属性是Predicate<T>

这是我的类的一个简化的例子:

public class ObjectAdapter
{
    public ObjectAdapter()
    {
        MemberFilter = DefaultFilter;
    }
    public Predicate<PropertyInfo> MemberFilter { get; set; }
    public virtual bool DefaultFilter(PropertyInfo info)
    {
        if (info.Name != "Test")
            return true;
        else
            return false;
    }
}

我的想法是,人们可以很容易地设置MemberFilter为他们想要的任何东西,因此没有必要做一个继承我的类并覆盖DefaultFilter函数。

问题:

在我的ObjectAdapter中,如果我尝试执行

something.GetType().GetProperties().Filter(MemberFilter)
我得到了这个奇怪的编译错误:
Error: cannot convert from 'System.Predicate<System.Reflection.PropertyInfo>' to 'System.Func<System.Reflection.PropertyInfo,bool>'

这对我来说没有意义,因为MemberFilter基本上是delegate bool Predicate<PropertyInfo>(PropertyInfo obj),应该与Func<PropertyInfo, bool>相同,对吧?

LINQ -使用谓词< >调用过滤器

您想使用Func<PropertyInfo, bool>Where代替,因为您不能自动将Predicate<PropertyInfo>转换为Func<PropertyInfo, bool>:

public class ObjectAdapter
{
    public ObjectAdapter()
    {
        MemberFilter = DefaultFilter;
    }
    public Func<PropertyInfo, bool> MemberFilter { get; set; }
    public virtual bool DefaultFilter(PropertyInfo info)
    {
        if (info.Name != "Test")
            return true;
        else
            return false;
    }
}

var oa = new ObjectAdapter();
var props= something.GetType().GetProperties().Where(oa.MemberFilter);

另一种选择是从Predicate<PropertyInfo>中创建Func<PropertyInfo, bool>:

public class ObjectAdapter
{
    public ObjectAdapter()
    {
        MemberFilter = DefaultFilter;
    }
    public Predicate<PropertyInfo> MemberFilter { get; set; }
    public virtual bool DefaultFilter(PropertyInfo info)
    {
        if (info.Name != "Test")
            return true;
        else
            return false;
    }
}

var oa = new ObjectAdapter();
Func<PropertyInfo, bool> func = new Func<PropertyInfo,bool>(oa.MemberFilter);
var props = something.GetType().GetProperties().Where(func);

问题是,虽然Predicate<T>Func<T,bool>对于相同类型的T具有相同的签名,但它们仍然是不同的(因此不兼容)委托类型。这个问题可以通过使用Func<T,bool>而不是Predicate<T>来解决,因为没有办法在它们之间直接转换