-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Implement ICollection<T> on several LINQ iterators #88249
Conversation
Tagging subscribers to this area: @dotnet/area-system-linq Issue DetailsThis adds I think the first commit here is pure goodness. It handles Enumerable.Empty, Enumerable.Repeat, and Enumerable.Range. The second commit is more valuable but also may need a little more scrutiny. It adds support for Enumerable.Select over arrays, lists, and ranges. This makes operations like
|
5cc7024
to
f3e281f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
`ICollection<T>` provides both a Count and a CopyTo, and `IList<T>` an indexer, all of which can make various consumption mechanisms more efficient. We only implement the interfaces when the underlying collection has a fixed size and all of the interface implementations are side-effect free (in particular, while appealing to do so, we don't implement them on various Select iterators). Some of the serialization tests need to be fixed as a result. The state of Queue's array is a bit different based on how its initialized, and such private details show up in BinaryFormatter output. Rather than special-casing the output per framework and core, I've just changed the test itself to ensure Queue can't see the size of the input collection.
54d1fc4
to
7aad8b7
Compare
This adds
ICollection<T>
implementations to several LINQ iterator types. This allows operations likelist.AddRange(enumerable)
to be significantly more efficient, as AddRange queries forICollection<T>
and then uses itsCount
/CopyTo
methods to directly populate the backing array.I think the first commit here is pure goodness. It handles Enumerable.Empty, Enumerable.Repeat, Enumerable.Range, and subsetting operations of IList, e.g. Take/Skip.
The second commit is more valuable but also may need a little more scrutiny. It adds support for Enumerable.Select over arrays, lists, and ranges. This makes operations like
list.AddRange(array.Select(i => ...))
much more efficient. However, becauseICollection<T>
providesContains
, invokingICollection<T>.Contains
will also invoke the selector function for every element examined. That's no different from if you usedEnumerable.Contains
, but in theory someone might be doing something likeif (source is ICollection<T> c) { ... issue multiple c.Contains calls }
, in which case they might silently start running the selector multiple times where they weren't previously.