IList<T>
没有AddRange()
方法。
如何在不通过迭代项并使用Add()
方法的情况下向IList<T>
添加一系列项目?
IList<T>
没有AddRange()
方法。
如何在不通过迭代项并使用Add()
方法的情况下向IList<T>
添加一系列项目?
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);
}
}
}
}
AddRange
是定义在 List<T>
上的,而不是接口上。
您可以将变量声明为 List<T>
而不是 IList<T>
,或者将其转换为 List<T>
,以便访问 AddRange
。
((List<myType>)myIList).AddRange(anotherList);
这种做法不够好(请参见下面的评论),因为一个 IList<T>
可能不是一个 List<T>
,而是实现了该接口的其他类型,并且很可能没有 AddRange
方法 - 在这种情况下,只有当您的代码在运行时抛出异常时才会发现。
因此,除非您确信该类型确实是 List<T>
,否则不应尝试使用 AddRange
。
一种方法是使用 is 或 as 运算符进行类型检测(自 C# 7 起)。
if(myIList is List<T>)
{
// can cast and AddRange
}
else
{
// iterate with Add
}
List<T>
(或者,如果这对你来说不是一个好选择,在需要AddRange
时进行转换以保持局部性 - 这是一项非常低成本的操作)。 - OdedList<T>
(例如数组)之外的任何东西上面,明显会抛出InvalidCastException
异常。 - bashis你可以这样做:
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版本时必须特别注意。 - jweyrich您也可以编写类似于以下内容的扩展方法:
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);
它仍然在迭代项,但您不必每次调用时编写迭代器或强制转换。
如果你要添加的是 List<T>
或者你能够调用 ToList()
,则可以使用 LINQ 的另一种答案:
IEnumerable<string> toAdd = new string[] {"a", "b", "c"};
IList<string> target = new List<string>();
toAdd.ToList().ForEach(target.Add);
IList没有AddRange()方法,但是有Concat()方法可以合并你的集合。
IList<T>.Concat(IEnumerable<T>)
返回连接后的序列作为可枚举对象,因此不会改变列表。这可能是期望的结果,也可能不是。 - Manfred
list
转换为List<T>
两次。其中一次可以使用as
关键字进行优化。 - bashisif (list is List<T> castedList) { castedList.AddRange(items); }
。意思是,如果list
是List<T>
类型的,就将它转换为castedList
,然后调用AddRange
方法添加元素items
到列表中。 - André Mantas