Linq query to select single string from multiple List<string>

c#, linq, string

Solution

In version 3, `select x` is returning a sequence of strings that match your critera; it just happens to be a sequence with one item in it.

`Console.WriteLine` internally calls `.ToString()` on whatever you pass into it. Since there is no meaningful string representation for `IEnumerable<T>`, the default in .NET is to print the string name of the type.

Based on your wording, I think part of your confusion does come from a misunderstanding of why version 2 works the way it does. In version 2, `select x.First()` is actually a bit of a quirk/coincidence, because a string is also an `IEnumerable<char>`, so you can do LINQ operations on the string. `.First()` returns the first element of that `char` sequence, for each result that matches your criteria. So you're saying:

"For each element which matches my criteria, select the first character, and then return the sequence of all the first characters for the matches."

So in fact, `item` in version 2 is an `IEnumerable<char>` with one element in it. Calling `Console.WriteLine()` on an `IEnumerable<char>` will just print the chars in order. So you get "i".

(note: I see after I answered this, the question was edited to call `.First()` both inside the projection and on the result, so the bit about passing `IEnumerable<char>` to `Console.WriteLine` isn't totally relevant anymore)

Keep in mind LINQ is pretty much about working with sets until you explicitly reduce them down. For example, `Select` is simply a projection or transformation. It returns the same number of items that were passed to it, transformed. `Where` reduces down the set, but it's still a set.

Problem

I am having a hard time understanding why I am getting the results that I am. I have two lists of strings: ``` var list1 = new List<String> {"item 1", "item 2"}; var list2 = new List<String> { "item 3", "item 4" }; ``` Version 1 - Output: "item 2" ``` var item = from x in (list1.Concat(list2)) where x.EndsWith("2") select x; Console.WriteLine(item.First()); ``` Version 2 - Output: "i" ``` var item = from x in (list1.Concat(list2)) where x.EndsWith("2") select x.First(); Console.WriteLine(item.First()); ``` Version 3 - Output: "System.Linq.Enumerable+WhereEnumerableIterator`1[System.String]" ``` var item = from x in (list1.Concat(list2)) where x.EndsWith("2") select x; Console.WriteLine(item); ``` Given that version 2 outputs "i", I would expect version 3 to output "item 2". Why is this behavior occurring?

Original source