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

返信ありがとうございます。この例のコードを単純化しようとしましたが、いつものように、悪魔は細部に宿っています!

.Where() ステートメントと AddRange() 呼び出しの間で、コードはソース (この例では「items」) リストを (深く) クリアしていました。開発者は、AddRange() 呼び出しが行われるまでフィルターが延期されたことに気付きませんでした。その時点で、ソース リストは既にクリアされていました。

プロットを失っていないことを知ってうれしい:)

于 2012-08-01T02:24:14.027 に答える
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 に答える