【发布时间】:2026-01-19 07:10:01
【问题描述】:
IList<T> 没有 AddRange() 方法。
如何在不遍历项目和使用Add() 方法的情况下将项目列表添加到IList<T>?
【问题讨论】:
标签: c# list collections addrange
IList<T> 没有 AddRange() 方法。
如何在不遍历项目和使用Add() 方法的情况下将项目列表添加到IList<T>?
【问题讨论】:
标签: c# list collections addrange
如果您查看C# source code for List<T>,我认为 List
查看源代码,您会看到 .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);
}
}
}
}
【讨论】:
list 转换为List<T> 两次。其中之一可以使用 as 关键字进行优化。
if (list is List<T> castedList) { castedList.AddRange(items); }
AddRange 是在 List<T> 上定义的,而不是在接口上。
您可以将变量声明为List<T> 而不是IList<T> 或将其强制转换为List<T> 以获得对AddRange 的访问权限。
((List<myType>)myIList).AddRange(anotherList);
这不是一个好的做法(请参阅下面的 cmets),因为 IList<T> 可能不是是 List<T>,但其他一些实现接口的类型很可能没有 @ 987654333@ 方法 - 在这种情况下,您只会发现代码在运行时抛出异常的时间。
因此,除非您确定该类型确实是 List<T>,否则您不应尝试使用 AddRange。
这样做的一种方法是使用 is 或 as 运算符测试类型(自 C# 7 起)。
if(myIList is List<T>)
{
// can cast and AddRange
}
else
{
// iterate with Add
}
【讨论】:
Concat,作为 @Self_Taught_Programmer answered。
List<T>(或者,如果这对您来说不是一个好的选择,请在您需要的地方进行转换@ 987654339@ 保持本地化 - 这是一个成本非常低的操作)。
List<T> 以外的任何东西(例如数组),它显然会抛出类似InvalidCastException 的东西。
你可以这样做:
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() 类似的功能。
【讨论】:
Enumerable.Concat 是由System.Linq.Enumerable 实现的,并且该方法的返回值是IEnumerable<TSource>,所以我认为它不应该被转换回IList<TSource> - 它由于不检查源代码我们不知道的实现细节,可能会返回其他内容 - 尽管不能保证它不会改变 - 因此在支持多个 .NET 版本时必须特别注意。
你也可以这样写一个扩展方法:
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);
它仍在迭代项目,但您不必每次调用它时都编写迭代或强制转换。
【讨论】:
另一个使用 LINQ 的答案,前提是您要添加的是 List<T> 或者您可以在其上调用 ToList():
IEnumerable<string> toAdd = new string[] {"a", "b", "c"};
IList<string> target = new List<string>();
toAdd.ToList().ForEach(target.Add);
【讨论】:
IList 没有 AddRange() ,但有 Concat() 结合你的收藏
【讨论】: