7

我有以下场景,我想将一些项目添加到列表中......

List<T> items = new List<T>();
IEnumerable<T> addItems = someCollection.Where(...);
items.AddRange(addItems);

使用此代码,不会将任何项目添加到列表中,但如果我在 Linq 语句之后添加 .ToList() 则项目会正确添加。我猜这是由于延迟执行,但我会认为给定 List.AddRange 函数接受一个 IEnumerable ,它将枚举要添加的项目。

有人可以澄清为什么会这样吗?

4

4 回答 4

4

我猜这是由于延迟执行,但我会认为给定 List.AddRange 函数接受一个 IEnumerable ,它将枚举要添加的项目。

确实如此。有一个短路ICollection<T>(在这种情况下您不会遇到),这将导致它使用ICollection<T>.CopyTo而不是枚举项目,否则,它将枚举集合。

对于一个工作示例,请尝试:

using System;
using System.Linq;
using System.Collections.Generic;

internal class Program
{
    private static List<T> RunQuery<T>(IEnumerable<T> someCollection, Func<T, bool> predicate)
    {
        List<T> items = new List<T>();
        IEnumerable<T> addItems = someCollection.Where(predicate);
        items.AddRange(addItems);
        return items;
    }

    static void Main()
    {
        var values = Enumerable.Range(0, 1000);

        List<int> results = RunQuery(values, i => i >= 500);

        Console.WriteLine(results.Count);
        Console.WriteLine("Press key to exit:");
        Console.ReadKey();
    }
}

这将使用您的确切代码,并将打印出 500(正确的项目数List<T>)。

于 2012-08-01T00:00:54.497 回答
3

我原以为 List.AddRange 函数接受一个 IEnumerable ,它将枚举要添加的项目。

我尝试了以下方法并且AddRange(IEnumerable<T>)确实有效

List<string> someCollection = new List<string>{"A", "B", "C"};
List<string> items = new List<string>();
IEnumerable<string> addItems = someCollection.Where(x => x != "");
items.AddRange(addItems);
于 2012-08-01T00:06:08.570 回答
2

它确实有效。这是一个证明它的单元测试:

[TestFixture]
public class AddRangeTest
{
    [Test]
    public void AddRange()
    {
        var list = new List<int>();
        var someCollection = new List<int> { 1, 2, 3 };
        var subItems = someCollection.Where(x => x > 1);
        list.AddRange(subItems);
        Assert.AreEqual(2, list.Count);
    }
}

也许在您的特定场景中有些东西无法正常工作。

于 2012-08-01T00:01:25.060 回答
2

感谢您的回复。我试图简化这个例子的代码,但像往常一样,魔鬼在细节中!

在 .Where() 语句和 AddRange() 调用之间,代码是(深入地)清除源(在本例中为“项目”)列表。开发人员没有意识到过滤器被推迟到 AddRange() 调用,此时他们已经清除了源列表。

很高兴知道我没有失去剧情:)

于 2012-08-01T02:24:14.027 回答