Why doesn't IDictionary<T, U> implement IReadOnlyDictionary<T, U>? #61281
-
I've been wondering this for quite a while... why doesn't the IDictionary<T, U> interface inherit from IReadOnlyDictionary<T, U>? All of IReadOnlyDictionary<>'s properties and methods already exist in IDictionary<>, therefore, IDictionary<> could inherit from IReadOnlyDictionary<> without any complications. However, it doesn't... why is that? Time and again I stumble upon a problem when creating extension methods for IReadOnlyDictionaries, since, using this snippet as an example:
The
You can see that now the Dictionary class cannot be extended by these methods, since their call is ambiguous. So, in order to make it work, the extension method would have to accept a generic object type which has to implement both IDictionary<> and IReadOnlyDictionary<>, which is represented here:
Despite everything, it still will not work as now the ambiguity has fallen to dict[], since both IDictionary<> and IReadOnlyDictionary<> have the property. So, in order to make this work fully, the following has to be done:
This will compile and work, but look at all the workaround that had to be done just because IDictionary<> does not inherit from IReadOnlyDictionary<>. A cast had to be used, grotesque calls to the extension method were made... all this because IReadOnlyDictionary<> isn't implemented by IDictionary<>. I would understand if IDictionary<> was used only as a setter, while IReadOnlyDictionary<> was the getter. Everything would then be justified, as the derived class would have to implement either or both, depending on its goal. But that's not the case, as the IReadOnlyDictionary<> interface has only methods read-only methods and properties, while IDictionary<> has for both cases. This even doesn't make much sense when building the interface itself. As it currently stands, the IDictionary<> and IReadOnlyDictionary<> interfaces are basically the following:
Witness how the IDictionary<> and IReadOnlyDictionary<> interfaces have redundant methods and properties. Why not just do this:
See how the ContainsKey method was absorbed into IDictionary<>. Sure, the You could also mention that the IDictionary<> interface implements ICollection<>, while IReadOnlyDictionary<> implements IReadOnlyCollection<>. I would then ask the same question I've asked, but regarding ICollection<>'s case instead. ICollection<> does everything that IReadOnlyCollection<> does and more, why not just make it implement it too? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
Duplicate (although specific) of #31001 |
Beta Was this translation helpful? Give feedback.
-
Answer in short: because it is a binary breaking change. Although having the same signature, the members like |
Beta Was this translation helpful? Give feedback.
-
This is only true if you recompile from source. For all packages involved (think nuget dependencies). This is what the other issue is talking about when they refer to "binary compatibility". So if your code was recompiled to use this change, but you were using packages that hadn't, things would explode.
Because there would have been issues with doing it when the interfaces were introduced, too.
Part of the problem here is that nothing's actually broken, risks involved are somewhat high, and there hasn't been a huge call to do this yet. And that aside, you still have to get somebody interested enough to make the change, on top of whatever more pressing issues they have to deal with. |
Beta Was this translation helpful? Give feedback.
This is only true if you recompile from source. For all packages involved (think nuget dependencies). This is what the other issue is talking about when they refer to "binary compatibility". So if your code was recompiled to use this change, but you were using packages that hadn't, things would explode.
Because there would have been issues with doing it when the interfaces were introduced, too.