代码之家  ›  专栏  ›  技术社区  ›  It's a trap

C#-向func添加条件会导致堆栈溢出异常

  •  0
  • It's a trap  · 技术社区  · 2 年前

    我有一个func作为规范类的一部分,它对给定的iqueryable进行排序

    Func<IQueryable<T>, IOrderedQueryable<T>>? Sort { get; set; }
    

    当我像下面这样向func添加多个条件时,它会导致堆栈溢出异常。

    spec.OrderBy(sc => sc.Case.EndTime).OrderBy(sc => sc.Case.StartTime);
    

    OrderBy方法是这样实现的

    public ISpecification<T> OrderBy<TProperty>(Expression<Func<T, TProperty>> property)
        {
            _ = Sort == null ? Sort = items => items.OrderBy(property) : Sort = items => Sort(items).ThenBy(property);
            return this;
        }
    

    链接或使用单独的线没有区别。

    如果我分配规范的一个新实例并将其设置为func,这个问题就会得到解决,但我不想每次都分配给一个新实例。请建议我这里缺少什么,以及如何重用同一个实例(如果可能的话)。

    1 回复  |  直到 2 年前
        1
  •  2
  •   Jon Skeet    2 年前

    这是有问题的部分:

    Sort = items => Sort(items)
    

    这就像编写一个调用自身的方法。

    你呢 希望 就是评估 现有的 Sort 功能,而不是“结果” 分类 评估时的财产”。

    我会这样重写这个方法:

    public ISpecification<T> OrderBy<TProperty>(Expression<Func<T, TProperty>> property)
    {
        var existingSort = Sort;
        Sort = existingSort is null
            ? items => items.OrderBy(property)
            : items => existingSort(items).ThenBy(property);
        return this;
    }
    

    (我也要附和施德荣的评论——这是一种有点违反直觉的方法,与正常的LINQ背道而驰。也许你有一些特别的理由反对LINQ对不变性和链接的期望,但这肯定是不寻常的。)