90

没有AddRange()办法IList<T>

如何在IList<T>不遍历项目和使用Add()方法的情况下将项目列表添加到?

4

6 回答 6

90

如果您查看List<T> 的 C# 源代码,我认为 List<T>.AddRange() 具有简单循环无法解决的优化。因此,扩展方法应该简单地检查 IList<T> 是否为 List<T>,如果是,则使用其本机 AddRange()。

查看源代码,您会看到 .NET 人员在他们自己的 LINQ 扩展中为 .ToList() 之类的东西做了类似的事情(如果它是一个列表,则强制转换它......否则创建它)。

public static class IListExtension
{
    public static void AddRange<T>(this IList<T> list, IEnumerable<T> items)
    {
        if (list == null) throw new ArgumentNullException(nameof(list));
        if (items == null) throw new ArgumentNullException(nameof(items));

        if (list is List<T> asList)
        {
            asList.AddRange(items);
        }
        else
        {
            foreach (var item in items)
            {
                list.Add(item);
            }
        }
    }
}
于 2015-10-13T13:36:30.137 回答
72

AddRange定义在 上List<T>,而不是接口上。

您可以将变量声明为List<T>代替IList<T>或将其强制转换List<T>为以获得对AddRange.

((List<myType>)myIList).AddRange(anotherList);

这不是好的做法(请参阅下面的注释),因为 aIList<T>可能不是a List<T>,而是实现接口的其他类型并且很可能没有AddRange方法 - 在这种情况下,您只会发现代码何时抛出运行时异常。

因此,除非您确定类型确实是 a List<T>,否则您不应该尝试使用AddRange.

一种方法是使用isas运算符测试类型(自 C# 7 起)。

if(myIList is List<T>)
{
   // can cast and AddRange
}
else
{
   // iterate with Add
}
于 2012-10-31T12:39:02.087 回答
24

你可以这样做:

IList<string> oIList1 = new List<string>{"1","2","3"};
IList<string> oIList2 = new List<string>{"4","5","6"};
IList<string> oIList3 = oIList1.Concat(oIList2).ToList();

所以,基本上你会使用Concat()扩展并ToList()获得与AddRange().

来源

于 2012-10-31T12:39:07.610 回答
9

你也可以这样写一个扩展方法:

internal static class EnumerableHelpers
{
    public static void AddRange<T>(this IList<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            collection.Add(item);
        }
    }
}

用法:

IList<int> collection = new MyCustomList(); //Or any other IList except for a fixed-size collection like an array
var items = new[] {1, 4, 5, 6, 7};
collection.AddRange(items);

它仍在迭代项目,但您不必每次调用它时都编写迭代或强制转换。

于 2015-07-17T13:32:01.610 回答
3

另一个使用 LINQ 的答案,前提是您要添加的内容是 aList<T>或者您可以调用ToList()它:

IEnumerable<string> toAdd = new string[] {"a", "b", "c"};
IList<string> target = new List<string>();

toAdd.ToList().ForEach(target.Add);
于 2020-07-17T23:49:31.830 回答
0

IList 没有 AddRange() ,但有 Concat() 结合你的收藏

于 2021-11-12T13:39:09.037 回答