C# 使用Linq筛选集合-如何重用同一筛选器

C# 使用Linq筛选集合-如何重用同一筛选器,c#,linq,C#,Linq,我正在筛选一个集合,并执行两个相同但针对不同字段的筛选器。 这里一定有办法减少代码的重复? 检查是否输入了日期,以及是否在用户输入的截止日期之前 public override IList<Company> Search() { var list = CacheObjects.Subcontractors; this.ApplicationFormReturnedCheck(ref list); this.Appli

我正在筛选一个集合,并执行两个相同但针对不同字段的筛选器。 这里一定有办法减少代码的重复? 检查是否输入了日期,以及是否在用户输入的截止日期之前

    public override IList<Company> Search()
    {
        var list = CacheObjects.Subcontractors;

        this.ApplicationFormReturnedCheck(ref list);

        this.ApplicationFormSentCheck(ref list);
    }

    private void ApplicationFormReturnedCheck(ref IList<Subcontractor> list)
    {
        if (this.ApplicationFormNotReturnedFlag == true && this.ApplicationFormReturned != null)
        {
            list =
                list.Where(x => x.ApplicationFormReturned == null || x.ApplicationFormReturned < this.ApplicationFormReturned).ToList();
        }
        else if (this.ApplicationFormNotReturnedFlag == true)
        {
            list = list.Where(x => x.ApplicationFormReturned == null).ToList();
        }
        else if (this.ApplicationFormReturned != null)
        {
            list = list.Where(x => x.ApplicationFormReturned < this.ApplicationFormReturned).ToList();
        }
    }

    private void ApplicationFormSentCheck(ref IList<Subcontractor> list)
    {
        if (this.ApplicationFormNotSentFlag == true && this.ApplicationFormSent != null)
        {
            list =
                list.Where(x => x.ApplicationFormSent == null || x.ApplicationFormSent < this.ApplicationFormSent).ToList();
        }
        else if (this.ApplicationFormNotSentFlag == true)
        {
            list = list.Where(x => x.ApplicationFormSent == null).ToList();
        }
        else if (this.ApplicationFormSent != null)
        {
            list = list.Where(x => x.ApplicationFormSent < this.ApplicationFormSent).ToList();
        }
    }
公共覆盖IList搜索()
{
var list=CacheObjects.contractor;
此.ApplicationFormReturnedCheck(参考列表);
此.ApplicationFormSentCheck(参考列表);
}
私有作废应用程序FormReturnedCheck(参考列表)
{
if(this.ApplicationFormNotReturnedFlag==true&&this.ApplicationFormReturned!=null)
{
名单=
其中(x=>x.ApplicationFormReturned==null | | x.ApplicationFormReturnedx.ApplicationFormReturned==null).ToList();
}
else if(this.ApplicationFormReturned!=null)
{
list=list.Where(x=>x.ApplicationFormReturnedx.ApplicationFormSent==null | | x.ApplicationFormSentx.ApplicationFormSent==null).ToList();
}
else if(this.ApplicationFormSent!=null)
{
list=list.Where(x=>x.ApplicationFormSent
A可用于封装通用谓词方法。在您的例子中,Func需要在构造函数中初始化,因为您正在过滤器中使用实例成员。例:

private readonly Func<Subcontractor, bool> _pred;

public Subcontractor()
{
    _pred = x => x.ApplicationFormReturned == null || x.ApplicationFormReturned < this.ApplicationFormReturned;
}

private void ApplicationFormReturnedCheck( ref IList<Subcontractor> list )
{
    if( this.ApplicationFormNotReturnedFlag == true && this.ApplicationFormReturned != null )
    {
        list = list.Where( _pred ).ToList();
    }
    else if( this.ApplicationFormNotReturnedFlag == true )
    {
        list = list.Where( x => x.ApplicationFormReturned == null ).ToList();
    }
    else if( this.ApplicationFormReturned != null )
    {
        list = list.Where( x => x.ApplicationFormReturned < this.ApplicationFormReturned ).ToList();
    }
}
private readonly Func\u pred;
公共分包商()
{
_pred=x=>x.ApplicationFormReturned==null | | x.ApplicationFormReturnedx.ApplicationFormReturned==null).ToList();
}
else if(this.ApplicationFormReturned!=null)
{
list=list.Where(x=>x.ApplicationFormReturned
A可用于封装通用谓词方法。在您的例子中,Func需要在构造函数中初始化,因为您正在过滤器中使用实例成员。例:

private readonly Func<Subcontractor, bool> _pred;

public Subcontractor()
{
    _pred = x => x.ApplicationFormReturned == null || x.ApplicationFormReturned < this.ApplicationFormReturned;
}

private void ApplicationFormReturnedCheck( ref IList<Subcontractor> list )
{
    if( this.ApplicationFormNotReturnedFlag == true && this.ApplicationFormReturned != null )
    {
        list = list.Where( _pred ).ToList();
    }
    else if( this.ApplicationFormNotReturnedFlag == true )
    {
        list = list.Where( x => x.ApplicationFormReturned == null ).ToList();
    }
    else if( this.ApplicationFormReturned != null )
    {
        list = list.Where( x => x.ApplicationFormReturned < this.ApplicationFormReturned ).ToList();
    }
}
private readonly Func\u pred;
公共分包商()
{
_pred=x=>x.ApplicationFormReturned==null | | x.ApplicationFormReturnedx.ApplicationFormReturned==null).ToList();
}
else if(this.ApplicationFormReturned!=null)
{
list=list.Where(x=>x.ApplicationFormReturned
我建议您可以做一些简单的事情,比如使用一些涵盖各种场景的
Func
实例。这是
Where
方法所期望的
Func
类型

为了演示,让我采用您的一种方法,并向您演示如何:

private void ApplicationFormReturnedCheck(ref IList<Subcontractor> list)
{
    var isFormReturned = new Func<Subcontractor,bool>(
          x => x.ApplicationFormReturned != null);
    var isBeforeDate = new Func<Subcontractor,bool>(
          x => x.ApplicationFormReturned < this.ApplicationFormReturned);
    var isFormReturnedOrBeforeDate= new Func<Subcontractor,bool>(
          x => isFormReturned(x) || isFormReturnedBeforeDate(x));

    if (this.ApplicationFormNotReturnedFlag == true && this.ApplicationFormReturned != null)
    {
        list = list.Where(isFormReturnedOrBeforeDate).ToList();
    }
    else if (this.ApplicationFormNotReturnedFlag == true)
    {
        list = list.Where(isFormReturned).ToList();
    }
    else if (this.ApplicationFormReturned != null)
    {
        list = list.Where(isBeforeDate).ToList();
    }
}
private void应用程序FormReturnedCheck(参考列表)
{
var isFormReturned=新函数(
x=>x.ApplicationFormReturned!=null);
var isBeforeDate=新函数(
x=>x.ApplicationFormReturnedisFormReturned(x)| | isFormReturnedBeforeDate(x));
if(this.ApplicationFormNotReturnedFlag==true&&this.ApplicationFormReturned!=null)
{
list=list.Where(isFormReturnedOrBeforeDate.ToList();
}
else if(this.ApplicationFormNotReturnedFlag==true)
{
list=list.Where(isFormReturned.ToList();
}
else if(this.ApplicationFormReturned!=null)
{
list=list.Where(isBeforeDate.ToList();
}
}
您展示的另一种方法虽然具有相似的逻辑,但使用了不同的变量集。(
ApplicationFormSent
代替
ApplicationFormReturned
)。依我看,你有两个选择

  • 使用不同的变量名在另一个方法中复制上述内容
  • 使用更复杂的方法,使这3个
    Func
    超出每个方法的范围,并能够区分要使用的变量(
    *已发送
    *已返回
    2的问题。上面提到的是,随着感知到的“重用”的增加,代码的可读性下降


    老实说,我看你的原始代码没有什么大问题!它清晰、简洁,并且很容易看到它在做什么。通过使用谓词(可以想象在类的其他地方)包装所有这些逻辑,您将使其更难阅读和维护。

    我建议您可以做一些简单的事情,例如使用一些涵盖各种场景的
    Func
    实例。这是
    Where
    方法所期望的
    Func
    类型

    为了演示,让我采用您的一种方法,并向您演示如何:

    private void ApplicationFormReturnedCheck(ref IList<Subcontractor> list)
    {
        var isFormReturned = new Func<Subcontractor,bool>(
              x => x.ApplicationFormReturned != null);
        var isBeforeDate = new Func<Subcontractor,bool>(
              x => x.ApplicationFormReturned < this.ApplicationFormReturned);
        var isFormReturnedOrBeforeDate= new Func<Subcontractor,bool>(
              x => isFormReturned(x) || isFormReturnedBeforeDate(x));
    
        if (this.ApplicationFormNotReturnedFlag == true && this.ApplicationFormReturned != null)
        {
            list = list.Where(isFormReturnedOrBeforeDate).ToList();
        }
        else if (this.ApplicationFormNotReturnedFlag == true)
        {
            list = list.Where(isFormReturned).ToList();
        }
        else if (this.ApplicationFormReturned != null)
        {
            list = list.Where(isBeforeDate).ToList();
        }
    }
    
    private void A