Why does IDictionary not implement IReadOnlyDictionary
I've recently just noticed that IDictionary does not implement IReadOnlyDictionary. I'm using two third-party libraries, one of which provides a ToDictionary() method which returns an IDictionary containing the contents, and another which consumes an IReadOnlyDictionary. In order to make this work, I've had to write the following ugly code: // IDictionary does not implement IReadOnlyDictionary, so we have to call .ToDictionary() // again to get a concrete dictionary implementation. var errors = result.ToDictionary().ToDictionary(x => x.Key, x => x.Value); From looking at the two interfaces, it seems that the methods in IReadOnlyDictionary are a direct subset of IDictionary: // Represents a generic read-only collection of key/value pairs. public interface IReadOnlyDictionary : IEnumerable, IEnumerable, IReadOnlyCollection { TValue this[TKey key] { get; } IEnumerable Keys { get; } IEnumerable Values { get; } bool ContainsKey(TKey key); bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value); } // Represents a generic collection of key/value pairs. public interface IDictionary : ICollection, IEnumerable, IEnumerable { TValue this[TKey key] { get; set; } ICollection Keys { get; } ICollection Values { get; } void Add(TKey key, TValue value); bool ContainsKey(TKey key); bool Remove(TKey key); bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value); } Some notable differences: The array index operator is get in the read-only version, and get/set in the writeable version. Would it be possible to specify this if inheriting from IReadOnlyDictionary? The Keys and Values are IEnumerable in the read-only version, and ICollection in the writeable version. This also doesn't make sense to me. When would you add a key to a dictionary without a value, or add a value to a dictionary without a key? I feel like it would make more sense for the writeable dictionary to also return IEnumerable or IReadOnlyCollection for these properties. The .Net team put a lot of thought into the core classes, so I assume the interfaces are separate by design. Does anyone know why the interfaces were created this way?
I've recently just noticed that IDictionary does not implement IReadOnlyDictionary. I'm using two third-party libraries, one of which provides a ToDictionary()
method which returns an IDictionary containing the contents, and another which consumes an IReadOnlyDictionary. In order to make this work, I've had to write the following ugly code:
// IDictionary does not implement IReadOnlyDictionary, so we have to call .ToDictionary()
// again to get a concrete dictionary implementation.
var errors = result.ToDictionary().ToDictionary(x => x.Key, x => x.Value);
From looking at the two interfaces, it seems that the methods in IReadOnlyDictionary
are a direct subset of IDictionary
:
// Represents a generic read-only collection of key/value pairs.
public interface IReadOnlyDictionary : IEnumerable>, IEnumerable, IReadOnlyCollection>
{
TValue this[TKey key] { get; }
IEnumerable Keys { get; }
IEnumerable Values { get; }
bool ContainsKey(TKey key);
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value);
}
// Represents a generic collection of key/value pairs.
public interface IDictionary : ICollection>, IEnumerable>, IEnumerable
{
TValue this[TKey key] { get; set; }
ICollection Keys { get; }
ICollection Values { get; }
void Add(TKey key, TValue value);
bool ContainsKey(TKey key);
bool Remove(TKey key);
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value);
}
Some notable differences:
- The array index operator is
get
in the read-only version, andget/set
in the writeable version. Would it be possible to specify this if inheriting from IReadOnlyDictionary? - The
Keys
andValues
are IEnumerable in the read-only version, and ICollection in the writeable version. This also doesn't make sense to me. When would you add a key to a dictionary without a value, or add a value to a dictionary without a key? I feel like it would make more sense for the writeable dictionary to also return IEnumerable or IReadOnlyCollection for these properties.
The .Net team put a lot of thought into the core classes, so I assume the interfaces are separate by design. Does anyone know why the interfaces were created this way?