Linq查询从多个List <string>中选择单个字符串

Joe*_*uer 4 c# linq string

我很难理解为什么我会得到我的结果.

我有两个字符串列表:

var list1 = new List<String> {"item 1", "item 2"};
var list2 = new List<String> { "item 3", "item 4" };
Run Code Online (Sandbox Code Playgroud)

版本1 - 输出:"第2项"

var item =
            from x in (list1.Concat(list2))
            where x.EndsWith("2")
            select x;

        Console.WriteLine(item.First());
Run Code Online (Sandbox Code Playgroud)

版本2 - 输出:"i"

var item =
            from x in (list1.Concat(list2))
            where x.EndsWith("2")
            select x.First();

        Console.WriteLine(item.First());
Run Code Online (Sandbox Code Playgroud)

版本3 - 输出:"System.Linq.Enumerable + WhereEnumerableIterator`1 [System.String]"

var item =
            from x in (list1.Concat(list2))
            where x.EndsWith("2")
            select x;

        Console.WriteLine(item);
Run Code Online (Sandbox Code Playgroud)

鉴于版本2输出"i",我希望版本3输出"第2项".为什么会出现这种情况?

Rex*_*x M 5

在版本3中,select x返回一个与您的critera匹配的字符串序列 ; 它恰好是一个包含一个项目的序列.

Console.WriteLine内部调用.ToString()你传入它的任何东西.由于没有有意义的字符串表示IEnumerable<T>,.NET中的默认值是打印该类型的字符串名称.

根据你的措辞,我认为你的混淆部分来自于误解为什么版本2以它的方式工作.在版本2中,select x.First()实际上有点怪癖/巧合,因为字符串也是一个IEnumerable<char>,所以你可以对字符串进行LINQ操作..First()返回char与您的条件匹配的每个结果的序列的第一个元素.所以你说:

"对于符合我标准的每个元素,选择第一个字符,然后返回匹配的所有第一个字符的序列."

所以实际上,item在版本2中IEnumerable<char>有一个元素.调用Console.WriteLine()上的IEnumerable<char>将只打印字符秩序.所以你得到"我".

(注意:我在回答之后看到,问题被编辑为调用.First()投影内部和结果,所以关于传递IEnumerable<char>的Console.WriteLine位置不再完全相关)

请记住,LINQ几乎是关于使用集合,直到您明确减少它们为止.例如,Select只是一个投影或转换.它返回传递给它的相同数量的项目,进行转换.Where缩小集合,但它仍然是一组.