Как Concat () в действительности объединяет коллекции на более низком уровне? - PullRequest
3 голосов
/ 13 мая 2010

Что на самом деле делает Линк?

Ответы [ 3 ]

9 голосов
/ 13 мая 2010

(я предполагаю, что это для 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() результата.)

1 голос
/ 13 мая 2010

Это зависит от поставщика LINQ, которого вы используете. LinqToSql или L2E могут использовать базу данных UNION, тогда как LINQ to Objects может просто перечислять обе коллекции по очереди.

1 голос
/ 13 мая 2010

Перечисляет каждую коллекцию по очереди и возвращает каждый элемент. Примерно так:

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, вы увидите, что итератор фактически реализован в отдельном методе)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...