Skip to content

Revisit ImmutableExtensions.TryCopyTo behavior for ICollection<T> #88181

Description

@adamsitnik

From #88093 (comment):

We should revisit this.

/// The reason we don't copy anything other than for well-known types is that a malicious interface
/// implementation of <see cref="ICollection{T}"/> could hold on to the array when its <see cref="ICollection{T}.CopyTo"/>
/// method is called. If the array it holds onto underlies an <see cref="ImmutableArray{T}"/>, it could violate
/// immutability by modifying the array.

That logic, while well-meaning, isn't worth making the implementations slower. If code wants to get at the underlying array of an ImmutableArray, there are easier ways, including a now fully supported public API.

The comment that triggered the conversation #88093 (comment):

The custom ToArray implementation is slower, because it uses CopyTo only for collections that implement IList<T>, while both KeyCollection and ValueCollection don't. They do implement ICollection<T> which is used by LINQ.

if (!sequence.TryCopyTo(array, 0))
{
int i = 0;
foreach (T item in sequence)
{
Requires.Argument(i < count);
array[i++] = item;

public sealed partial class KeyCollection : System.Collections.Generic.ICollection<TKey>, System.Collections.Generic.IEnumerable<TKey>, System.Collections.Generic.IReadOnlyCollection<TKey>, System.Collections.ICollection, System.Collections.IEnumerable

public sealed partial class ValueCollection : System.Collections.Generic.ICollection<TValue>, System.Collections.Generic.IEnumerable<TValue>, System.Collections.Generic.IReadOnlyCollection<TValue>, System.Collections.ICollection, System.Collections.IEnumerable

cc @stephentoub

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions