AddRange to a Collection

Viewed 155488

A coworker asked me today how to add a range to a collection. He has a class that inherits from Collection<T>. There's a get-only property of that type that already contains some items. He wants to add the items in another collection to the property collection. How can he do so in a C#3-friendly fashion? (Note the constraint about the get-only property, which prevents solutions like doing Union and reassigning.)

Sure, a foreach with Property. Add will work. But a List<T>-style AddRange would be far more elegant.

It's easy enough to write an extension method:

public static class CollectionHelpers
{
    public static void AddRange<T>(this ICollection<T> destination,
                                   IEnumerable<T> source)
    {
        foreach (T item in source)
        {
            destination.Add(item);
        }
    }
}

But I have the feeling I'm reinventing the wheel. I didn't find anything similar in System.Linq or morelinq.

Bad design? Just Call Add? Missing the obvious?

9 Answers

Here is a bit more advanced/production-ready version:

    public static class CollectionExtensions
    {
        public static TCol AddRange<TCol, TItem>(this TCol destination, IEnumerable<TItem> source)
            where TCol : ICollection<TItem>
        {
            if(destination == null) throw new ArgumentNullException(nameof(destination));
            if(source == null) throw new ArgumentNullException(nameof(source));

            // don't cast to IList to prevent recursion
            if (destination is List<TItem> list)
            {
                list.AddRange(source);
                return destination;
            }

            foreach (var item in source)
            {
                destination.Add(item);
            }

            return destination;
        }
    }

Or you can just make an ICollection extension like this:

 public static ICollection<T> AddRange<T>(this ICollection<T> @this, IEnumerable<T> items)
    {
        foreach(var item in items)
        {
            @this.Add(item);
        }

        return @this;
    }

Using it would be just like using it on a list:

collectionA.AddRange(IEnumerable<object> items);

Agree with some guys above and Lipert's opinion. In my case, it's quite often to do like this:

ICollection<int> A;
var B = new List<int> {1,2,3,4,5};
B.ForEach(A.Add);

To have an extension method for such operation a bit redundant in my view.

Related