Skip to content

List<T>.AddRange with erroneous input has inconsistent behavior #76116

@theodorzoulias

Description

@theodorzoulias

Description

Out of curiosity I experimented with the List<T>.AddRange method, by passing as argument a custom ICollection<T> implementation with maximum Count and no-op CopyTo. The behavior changes depending on the existing size of the list, and may result in a negative List<T>.Count value.

Reproduction Steps

Here is my custom ICollection<T>:

class MyCollection<T> : ICollection<T>
{
    public int Count => Int32.MaxValue;
    public void CopyTo(T[] array, int arrayIndex) { } // Do nothing

    public bool IsReadOnly => throw new NotImplementedException();
    public void Add(T item) => throw new NotImplementedException();
    public bool Remove(T item) => throw new NotImplementedException();
    public void Clear() => throw new NotImplementedException();
    public bool Contains(T item) => throw new NotImplementedException();
    public IEnumerator<T> GetEnumerator() => throw new NotImplementedException();
    IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
}

Passing an instance to List<T>.AddRange I expected to get an exception of some kind, which is indeed what happens:

new List<int>().AddRange(new MyCollection<int>());

Output:

System.OutOfMemoryException: Array dimensions exceeded supported range.
   at System.Collections.Generic.List`1.set_Capacity(Int32 value)
   at System.Collections.Generic.List`1.Grow(Int32 capacity)
   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
   at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection)
   at Program.Main(String[] args) in C:\Projects\Console1\Program.cs:line 9

But if the list is not empty before the AddRange, then there is no exception:

List<int> list = new();
list.Add(1);
list.AddRange(new MyCollection<int>());
Console.WriteLine($"list.Count: {list.Count}, list.Capacity: {list.Capacity}");

Output:

list.Count: -2147483648, list.Capacity: 8

Online demo.

Configuration

  • .NET 6.0
  • Console application
  • 64-bit operating system, x64-based processor

This is not a realistic scenario, since the MyCollection<T> is not correctly implemented, but nevertheless I thought I should report it.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions