【问题标题】:How does Concat() actually join the collections at lower level?Concat() 如何实际加入较低级别的集合?
【发布时间】:2010-05-13 15:57:51
【问题描述】:

Linq 实际上在做什么?

【问题讨论】:

    标签: c# linq collections


    【解决方案1】:

    (我假设这是针对 LINQ to Objects 的。其他任何东西都会以不同的方式实现:)

    它只是从第一个返回所有内容,然后从第二个返回所有内容。所有数据都是流式传输的。像这样的:

    public static IEnumerable<T> Concat(this IEnumerable<T> source1,
        IEnumerable<T> source2)
    {
        if (source1 == null)
        {
            throw new ArgumentNullException("source1");
        }
        if (source2 == null)
        {
            throw new ArgumentNullException("source1");
        }
        return ConcatImpl(source1, source2);
    }
    
    
    private static IEnumerable<T> ConcatImpl(this IEnumerable<T> source1,
        IEnumerable<T> source2)
    {
        foreach (T item in source1)
        {
            yield return item;
        }
        foreach (T item in source2)
        {
            yield return item;
        }
    }
    

    我已将其拆分为两种方法,以便可以急切地执行参数验证,但我仍然可以使用迭代器块。 (直到第一次调用 MoveNext() 结果,迭代器块中的代码才会被执行。)

    【讨论】:

    • @Jon:我不确定我是否完全理解您的评论:如果全部采用一种方法会有什么不同?
    • @Steven:在创建 LINQ 表达式时调用 Concat(因为 return)。 ConcatImpl 在评估 LINQ 表达式时被调用(因为 yield return)。 @Jon:我很喜欢,但是男孩你快吗。也许我只会在您的时间凌晨 3 点时尝试回答。 :)
    • @Stephen:好的,为了确保我理解正确,你是说 ConcatImpl 立即返回一个迭代器块而不执行任何操作,直到 MoveNext 被调用(通过 foreach),而 Concat 立即执行,允许现在而不是以后检查参数。对吗?
    • 请注意,这会影响性能; Concat 的幼稚实现并未针对串联组合的情况进行优化。请参阅 blogs.msdn.com/wesdyer/archive/2007/03/23/… 了解对简单组合连接的性能的分析。
    • @Eric:我想要自己的时区,无论我走到哪里都可以随身携带……唯一的时间就是咖啡时间。
    【解决方案2】:

    它依次枚举每个集合,并产生每个元素。类似的东西:

    public static IEnumerable<T> Concat<T>(this IEnumerable<T> source, IEnumerable<T> other)
    {
        foreach(var item in source) yield return item;
        foreach(var item in other) yield return item;
    }
    

    (如果你查看使用 Reflector 的实际实现,你会发现迭代器实际上是在单独的方法中实现的)

    【讨论】:

      【解决方案3】:

      这取决于您使用的 LINQ 提供程序。 LinqToSql 或 L2E 可能使用数据库 UNION,而 LINQ to Objects 可能只是依次为您枚举这两个集合。

      【讨论】:

        猜你喜欢
        • 2018-12-17
        • 2012-03-06
        • 2021-10-22
        • 2016-04-28
        • 2023-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多