How to add a range of items to an IList?

C#ListCollectionsAddrange

C# Problem Overview


There is no AddRange() method for IList<T>.

How can I add a list of items to an IList<T> without iterating through the items and using the Add() method?

C# Solutions


Solution 1 - C#

If you look at the C# source code for List<T>, I think List<T>.AddRange() has optimizations that a simple loop doesn't address. So, an extension method should simply check to see if the IList<T> is a List<T>, and if so use its native AddRange().

Poking around the source code, you see the .NET folks do similar things in their own LINQ extensions for things like .ToList() (if it is a list, cast it... otherwise create it).

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);
            }
        }
    }
}

Solution 2 - C#

AddRange is defined on List<T>, not the interface.

You can declare the variable as List<T> instead of IList<T> or cast it to List<T> in order to gain access to AddRange.

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

This is not good practice (see comments below), as an IList<T> might not be a List<T>, but some other type that implemented the interface and may very well not have an AddRange method - in such a case, you will only find out when your code throws an exception at runtime.

So, unless you know for certain that the type is indeed a List<T>, you shouldn't try to use AddRange.

One way to do so is by testing the type with the is or as operators (since C# 7).

if(myIList is List<T>)
{
   // can cast and AddRange
}
else
{
   // iterate with Add
}

Solution 3 - C#

You could do something like this:

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();

So, basically you would use the Concat() extension and ToList() to get a similar functionality as AddRange().

Source

Solution 4 - C#

You could also write an extension method like this:

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

Usage:

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);

Which is still iterating over items, but you don't have to write the iteration or cast every time you call it.

Solution 5 - C#

Another answer using LINQ, provided the thing you're adding is a List<T> or you are able to call ToList() on it:

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

toAdd.ToList().ForEach(target.Add);

Solution 6 - C#

IList don't has AddRange() ,but has Concat() which combine yours collection

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmohsen dorparastiView Question on Stackoverflow
Solution 1 - C#BlackjacketMackView Answer on Stackoverflow
Solution 2 - C#OdedView Answer on Stackoverflow
Solution 3 - C#RayshawnView Answer on Stackoverflow
Solution 4 - C#bashisView Answer on Stackoverflow
Solution 5 - C#RedRainView Answer on Stackoverflow
Solution 6 - C#edenaView Answer on Stackoverflow