Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Enumerable.Concat always append at the end of the first collection?

Does Enumerable.Concat always append at the end of the first collection?

Example:

object someObject = new object();
List<object> listA = new List<object>();
listA.Add(new int());
object item = listA.Concat(new object[] { (object)new float() }).FirstOrDefault();

Is it guaranteed that the item will be int not float after Concat on every use? That means:

[0] int
[1] float

The MSDN says nothing about element order in resulting collection, however examples show that the order is elements from first collection then elements from second collection.

like image 731
user2475983 Avatar asked Feb 14 '17 09:02

user2475983


People also ask

Does concat preserve order?

The Concat operator is defined for ordered multisets where the orders of the receiver and the argument are the same. Ordering in SQL is the final step before results are produced. For this reason, the Concat operator is implemented by using UNION ALL and does not preserve the order of its arguments.

How can I add an item to a IEnumerable T collection?

You cannot, because IEnumerable<T> does not necessarily represent a collection to which items can be added. In fact, it does not necessarily represent a collection at all! For example: IEnumerable<string> ReadLines() { string s; do { s = Console.


1 Answers

Concat is a LINQ method. That means it's a query. It does not create a list or some other kind of collection but a sequence.

So what Concat actually does is combining the two source sequences. When you iterate through the result of Concat you first iterate through the first sequence and then through the second sequence. The sequence are thereby never changed.

So, yes

the item will be int not float after Concat on every use


The MSDN says nothing about element order

Well it does say

Concatenates two sequences.

And to concatenate means to put one after the other, not to mix them up.


From the reference source:

public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {
    if (first == null) throw Error.ArgumentNull("first");
    if (second == null) throw Error.ArgumentNull("second");
    return ConcatIterator<TSource>(first, second);
}

static IEnumerable<TSource> ConcatIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second) {
    foreach (TSource element in first) yield return element;
    foreach (TSource element in second) yield return element;
}

So you see the two consecutive foreach will first yield the elements of the first sequence, then the element of the second sequence.

like image 52
René Vogt Avatar answered Oct 23 '22 12:10

René Vogt