(Edit: I was tired and I screwed up the example a bit. All fixed now)
Given the work they are doing around covariance and contravariance in 4.0, I think this idea makes a lot of sense. It makes so
much sense that I think the only reason they might not do it is for reasons of backwards compatibility (I have no idea if that would be an issue or not). To take this to an insane level, what about splitting the interfaces between IReadOnlyBlah and IMutableBlah
and an IBlah that derives and unifies both? Why IMutableBlah? Suppose:
var bars = new List<Bar>(); ... PopulateFoos(bars); // Look, Ma! No casting or converting!
I never expected this, but I received a reply very quickly from Kim Hamilton of the BCL team. Here's what Kim wrote:
Hi Tommy, Thanks for the excellent feedback! We're considering similar collections interface refactorings (such as you described) -- not only to allow more appropriate read-only interfaces, but also to expand support for covariance and contravariance. Note that IEnumerable<T>
and IEnumerable<T> are the only collections interfaces that work with CLI variance support currently. That includes a restriction on T being exclusively in the "in" or "out" position (see Eric Lippert's blogs on variance support on C# for more details). The
interface hierarchy you described _almost_ allows a covariant IReadOnlyCollection<T> but read-only properties like Contains are a problem (T in the input position). I'd like to solve both problems at the same time. There are possibilities but they're slightly
less elegant than the nice hierarchy to solve just the read-only problem.
In any case, we're definitely interested in such an API enhancement and I'm glad to hear that you'd find this useful. Thanks! Kim