Runtime: System.Collections: Dictionary.Empty<K, V>()

Created on 2 Nov 2017  路  6Comments  路  Source: dotnet/runtime

Concrete implementations of IDictionary<K, V> and IReadOnlyDictionary<K, V> do not provide Empty singletons, per those for Array.Empty and Enumerable.Empty.
This proposal would permit the same idiom to be available for Dictionary.

Rationale and Usage

This is a nice-to-have, but helps in environments where resources are constrained. The current idiom is to create a new Dictionary<K, V>(0) but that incurs not-insignificant private state, and the semantics of 'immutably empty' are different to those for 'empty but not populated yet'.

There are several data structures that build up maps of maps, for example System.Json. In scenarios where datasets are large, the cost and semantics of pseudo-empty add up.

For scenarios where we have lists instead of maps, we already use Array.Empty<T> or Enumerable.Empty<T>. It would be consistent to provide the same facility for maps.

```C#
var empty = Dictionary.Empty();
empty.Count; // 0
empty.IsReadOnly; // true
empty["hi"]; // KeyNotFound or InvalidOperation (?)
empty.Add(...); // InvalidOperation
Keys; // Array.Empty

# Proposed API
```C#
    public static class Dictionary // See open questions
    {
        /// <summary>
        /// Returns an empty dictionary that is immutable.
        /// </summary>
        /// <typeparam name="TKey">The type of keys in the dictionary.</typeparam>
        /// <typeparam name="TValue">The type of values in the dictionary.</typeparam>
        /// <returns>Returns an empty <see cref="IDictionary{TKey, TValue}".</returns>
        public static IDictionary<TKey, TValue> Empty<TKey, TValue>() => <singleton impl>;
    }

    public static class ReadOnlyDictionary
    {
        /// <summary>
        /// Returns an empty dictionary that is immutable.
        /// </summary>
        /// <typeparam name="TKey">The type of keys in the dictionary.</typeparam>
        /// <typeparam name="TValue">The type of values in the dictionary.</typeparam>
        /// <returns>Returns an empty <see cref="IReadOnlyDictionary{TKey, TValue}".</returns>
        public static IReadOnlyDictionary<TKey, TValue> ReadOnlyEmpty<TKey, TValue>() => <singleton impl>;
    }

Details

The singletons would return sensible defaults where possible for getters, though indexers would need to throw. Since IsReadOnly==true, mutators should throw too.
All errors should align with those used when a traditional Dictionary has 'IsReadOnly=true`.

Open Questions

  • I am not sure what namespace & class name to use, since the chance of conflict (in user code) is high if we used public static class Dictionary to host the Empty singleton. Ditto for ReadOnlyDictionary.
  • I initially thought that the immutable nature of Dictionary.Empty might surprise or confuse users, but if we set IsReadOnly=true then it should cause less friction. ReadOnlyDictionary.Empty is already expected to be immutable, so it should not have the same problem.
  • Not sure exactly what errors to throw in the indexers and mutators. See previous bullet.

Prototype comprises 3 classes; ReadOnlyDictionary class, Dictionary class and Singleton implementation.

Pull Request

I am happy to contribute the PR, when/if we gain consensus

Updates

Happy to PR, but would especially need guidance on namespace, naming, decision on immutability.

api-suggestion area-System.Collections

Most helpful comment

This already exists, the method is called ImmutableDictionary.Create<TKey, TValue>() (or ImmutableDictionary<TKey, TValue>.Empty). The returned type implements both IDictionary<TKey, TValue> and IReadOnlyDictionary<TKey, TValue>. I'm not sure what would be the point of creating another version of that method under a different name.

All 6 comments

@grant-d your API proposals are welcome, but could you please format them into sections as suggested in example linked from https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/api-review-process.md?
The standard format greatly helps the review process.

No problem - let me know if this update is suitable

cool, as for any issue, if you don't get a response from area owner in a few days, you can ping them: https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/issue-guide.md

@safern or聽@ianhays please comment on tis proposal.

This already exists, the method is called ImmutableDictionary.Create<TKey, TValue>() (or ImmutableDictionary<TKey, TValue>.Empty). The returned type implements both IDictionary<TKey, TValue> and IReadOnlyDictionary<TKey, TValue>. I'm not sure what would be the point of creating another version of that method under a different name.

Thanks svick, I had looked in various places for such functionality, but missed ImmutableDictionary.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bencz picture bencz  路  3Comments

jchannon picture jchannon  路  3Comments

Timovzl picture Timovzl  路  3Comments

v0l picture v0l  路  3Comments

omariom picture omariom  路  3Comments