1

我正在过滤一个集合,并执行 2 个相同但针对不同字段的过滤器。必须有一种方法可以减少这里的代码重复?检查是否已输入日期,以及是否在用户输入的截止日期之前。

    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();
        }
    }
4

2 回答 2

1

我建议您可以做一些简单的事情,例如有一些Func<Subcontractor,bool>涵盖您的各种场景的实例。这是FuncWhere方法期望的类型

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

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();
    }
}

您展示的另一种方法虽然具有相似的逻辑,但使用了一组不同的变量。(ApplicationFormSent代替ApplicationFormReturned)。在我看来,你有两个选择

  1. 在其他方法中复制上述内容,使用不同的变量名
  2. 使用更复杂的方法,使这 3Func超出每种方法的范围,并且能够区分要使用的变量(*Sent*Returned)。

上面 2. 的问题在于,随着您感知的“重用”增加,代码的可读性下降。

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

于 2013-05-29T15:48:28.363 回答
0

Func(T, TResult)可用于封装常用谓词方法。在您的情况下,由于您在过滤器中使用实例成员,因此需要在构造函数中初始化 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();
    }
}
于 2013-05-29T15:44:49.870 回答