Skip to content

Dictionary, List and other Collection should have Empty concept #38340

@juliusfriedman

Description

@juliusfriedman

Background and Motivation

Like Array.Empty one typically wants an empty version of a collection. We already have as @vcsjones pointed out below:

ImmutableDictionary<TKey,TValue>.Empty Field
ImmutableHashSet.Empty Field
ImmutableList.Empty Field

These are not easily discover-able from the types which most developers start out using e.g. List<T>, Dictionary<TKey,TValue>, HashSet<T>.

There is also the ISet<T> Interface to which one can easily use Enumerable.Empty<T>(); to fulfill.

ICollection<T> implements System.Collections.Generic.IEnumerable<T> and adds Count and IsReadOnly

One can easily use

System.Collections.Generic.ICollection<int> test = (System.Collections.Generic.ICollection<int>)Array.Empty<int>();

However one cannot use

System.Collections.Generic.ICollection<int> test = (System.Collections.Generic.ICollection<int>)Enumerable.Empty<int>(); as it gives a:

Unable to cast object of type 'System.Linq.EmptyPartition1[System.Int32]' to type 'System.Collections.Generic.ICollection1[System.Int32]'.
--

See also: Partition.SpeedOpt.cs EmptyPartition<T>

See also: #27552

Proposed API

namespace System.Linq
{
     internal sealed class EmptyPartition<TElement> : IPartition<TElement>, IEnumerator<TElement>,  
+ ICollection<TElement>{
+ internal static  readonly EmptyPartition<TElement> Empty => new EmptyPartition<TElement>();
+ ICollection<TElement>.Count => 0;
+ ICollection<TElement>.IsReadyOnly => true;
}
namespace System.Collections.Generic
{
     public interface ICollection<T> : System.Collections.Generic.IEnumerable<T>{
+ ICollection<T> GetDefaultEmptyCollection() => EmptyPartition<T>.Empty;
}

Hopefully this also allows for it to be derived and overridden if required, not sure with DIM's.

Usage Examples

Especially useful once nullable enable is applied, you either have to choose to annotate the types that they may return null or you can use the Empty Sentinel.

Alternative Designs

Default implementation methods on IDictionary, EmptyCollections class or additions to almost all collections.

Make EmptyParition public and point to it's Empty member explicitly from ICollection

Risks

Low , Similar to someone hijacking new or Array Constructor or patching the Empty method itself.

Benefits

It provides a more straight forward way to create non null returning API's and you don't have to create the Sentinel yourself. Albeit is trivial to have such a EmptyCollection class with these required sentinel values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions