Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[API Proposal]: ICollection<> AddRange / RemoveRange #98509

Open
Daniel-Svensson opened this issue Feb 15, 2024 · 2 comments
Open

[API Proposal]: ICollection<> AddRange / RemoveRange #98509

Daniel-Svensson opened this issue Feb 15, 2024 · 2 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Collections
Milestone

Comments

@Daniel-Svensson
Copy link
Contributor

Daniel-Svensson commented Feb 15, 2024

Background and motivation

It is not quite uncommon to add several items at a time to a collection, which currently requires a loop with multiple calls to .Add if the exact type of collection is not known at compile type.

Many collection types including List<T>, HashSet<T> and hopefully soon? (#18087) Collection<T> ObservableCollection<T> provides optimized methods providing bulk Add and remove.
By adding new methods to ICollection it becomes possible to easily write both succint and performant code

The addition of range api's to ICollection would not only make it more convenient to work with collections, it could also make common operations faster.

API Proposal

namespace System.Collections.Generic;

public interface ICollection<T>
{
    // Adds the elements of the specified collection the ICollection<T>.
   // <remarks>The method is not atomic </remarks>
    void AddRange(IEnumerable<T> collection)
    {
       ArgumentNullException.ThrowIfNull(collection);
       
        foreach(item in collection)
           Add(item);
    }

    // Removes the elements of the specified collection the ICollection<T>.
   // <remarks>The method is not atomic </remarks>
   // This is mostly for symmetry with add, I only expect it to be performant for hashset (and somewhat for observable collection)
    void RemoveRange(IEnumerable<T> collection)
    {
        ArgumentNullException.ThrowIfNull(collection);

        foreach(item in collection)
            Remove(item);
    }
}

API Usage

Assume we have extracted some keywords to attach to a blog entry.

// blogPost .KeyWords has type ICollection<string>
BlogPost blogPost = ...;
List<string> keywords = ExtractTags(blogPost.Text);

Then they can easily be added

blogPost.Keywords.AddRange(keywords);

Current alternatives:

keywords.ForEach(x => blogPost.Keywords.Add(x));
// or 
foreach(string keyword in keywords)
    blogPost.Keywords.Add(keyword);

Alternative Designs

Risks

  • To avoid making this a possible Binary Breaking change. Something similar to the proposal to allow adding 'fallback' DIM methods suggested in #31001 should also be implemented
  • 3'rd party Collection interfaces who has already added something might get compilation Warnings/Info when compiling against newer .NET versions, that they need to use "new" if they wan't a separate method slot with the same name.
@Daniel-Svensson Daniel-Svensson added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Feb 15, 2024
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Feb 15, 2024
@ghost
Copy link

ghost commented Feb 15, 2024

Tagging subscribers to this area: @dotnet/area-system-collections
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and motivation

It is not quite uncommon to add several items at a time to a collection, which currently requires a loop with multiple calls to .Add if the exact type of collection is not known at compile type.

Many collection types including List<T>, HashSet<T> and hopefully soon? (#18087) Collection<T> ObservableCollection<T> provides optimized methods providing bulk Add and remove.
By adding new methods to ICollection it becomes possible to easily write both succint and performant code

The addition of range api's to ICollection would not only make it more convenient to work with collections, it could also make common operations faster.

API Proposal

namespace System.Collections.Generic;

public interface ICollection<T>
{
    // Adds the elements of the specified collection the ICollection<T>.
   // <remarks>The method is not atomic </remarks>
    void AddRange(IEnumerable<T> collection)
    {
       ArgumentNullException.ThrowIfNull(collection);
       
        foreach(item in collection)
           Add(item);
    }

    // Removes the elements of the specified collection the ICollection<T>.
   // <remarks>The method is not atomic </remarks>
    void RemoveRange(IEnumerable<T> collection)
    {
        ArgumentNullException.ThrowIfNull(collection);

        foreach(item in collection)
            Remove(item);
    }
}

API Usage

Assume we have extracted some keywords to attach to a blog entry.

// blogPost .KeyWords has type ICollection<string>
BlogPost blogPost = ...;
List<string> keywords = ExtractTags(blogPost.Text);

Then they can easily be added

blogPost.Keywords.AddRange(keywords);

Current alternatives:

keywords.ForEach(x => blogPost.Keywords.Add(x));
// or 
foreach(string keyword in keywords)
    blogPost.Keywords.Add(keyword);

Alternative Designs

Risks

  • To avoid making this a possible Binary Breaking change. Something similar to the proposal to allow adding 'fallback' DIM methods suggested in #31001 should also be implemented
  • 3'rd party Collection interfaces who has already added something might get compilation Warnings/Info when compiling against newer .NET versions, that they need to use "new" if they wan't a separate method slot with the same name.
Author: Daniel-Svensson
Assignees: -
Labels:

api-suggestion, area-System.Collections

Milestone: -

@eiriktsarpalis
Copy link
Member

This falls under the usual issues of retroactively introducing DIMs to existing interface types, which is known to have the potential to introduce both source breaking changes and run-time breaking changes. Given the prevalence of methods called AddRange in collection interface types, it is likely that such conditions will get hit in our downstream dependencies.

In any case, the success of #95830 will most likely inform how we approach similar requests in the future.

@eiriktsarpalis eiriktsarpalis removed the untriaged New issue has not been triaged by the area owner label Mar 11, 2024
@eiriktsarpalis eiriktsarpalis added this to the Future milestone Mar 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Collections
Projects
None yet
Development

No branches or pull requests

2 participants