4

在以下代码中:

var cats = new List<string>() {"cat1", "cat2"};
var dogs = new List<string>() {"dog1", "dog2"};

var animals = new List<Animal>();

animals = (cats.Select(x => new Animal() {Type = "Cat", Name = x}).ToList().AddRange(
                        dogs.Select(x => new Animal() {Type = "Dog", Name = x}).ToList())).ToList();

最后调用 ToList() 是一个错误,因为 AddRange() 返回 void。现在使用 Linq 类型查询时,这似乎不正确。

我发现我可以将其更改为.Union().Concat()解决问题,但不AddRange()应该更新,或者它是否有理由返回无效?

4

4 回答 4

6

AddRange更改基础 List 对象。没有 LinQ 方法可以做到这一点。所以它根本不同,不应该在 LinQ 连接中使用。它的返回值void反映了这一点。

于 2013-06-03T15:03:25.547 回答
5

你已经回答了你自己的问题。如果您想从两个列表中获得不同的值,请使用 Union,如果您只想加入两个列表,请使用 Concat。一旦加入了两个可枚举项,您就可以调用 ToList()。

AddRange 是 List 自身的一个方法,与 LINQ 没有任何关系。

于 2013-06-03T15:02:56.630 回答
2

AddRange是一种List<T>早于 LINQ 的方法。它会在原地改变当前列表,因此不需要返回它(它也不遵循你现在经常发现的流畅语法风格)。List<T>不是不可变的,所以变异方法调用很好。

有一些 linq 方法可以将列表连接在一起(正如您在问题中所指出的那样)。我倾向于不会在 linq 方法链中嵌入变异操作,因为它违背了 linq 只是一个查询/投影设置并且不会“更新”事物的一般想法。

于 2013-06-03T15:00:53.583 回答
2

在您的情况下,最好使用Enumerable.Concat

animals = cats.Select(x => new Animal() {Type = "Cat", Name = x})
                .Concat(dogs.Select(x => new Animal() {Type = "Dog", Name = x})).ToList();
于 2013-06-03T15:03:54.773 回答