views:

267

answers:

3

The IDictionary<TKey, TValue> in .NET 4 / Silverlight 4 does not support covariance, i.e. I can't do a

IDictionary<string, object> myDict = new Dictionary<string, string>();

analog to what I can do with IEnumerable<T>s now.

Probably boils down to the KeyValuePair<TKey, TValue> not being covariant either. I feel that covariance should be allowed in dictionaries at least for the values.

So is that a bug or a feature? Will it ever come, maybe in .NET 37.4?

+16  A: 

It's a feature. .NET 4.0 only supports safe covariance. The cast you mentioned is potentially dangerous as you could add a non-string element to the dictionary if that was possible:

IDictionary<string, object> myDict = new Dictionary<string, string>();
myDict["hello"] = 5; // not an string

On the other hand, IEnumerable<T> is a read-only interface. The T type parameter is only in its output positions (return type of the Current property) so it's safe to treat IEnumerable<string> as an IEnumerable<object>.

Mehrdad Afshari
Ahh ok, of course, I indeed was intending for read-only use. The .NET library surely does miss a read-only Dictionary type. Someone should post another question about that issue one of these days. ;-)
herzmeister der welten
+3  A: 

But then you could say

myDict.Add("Hello, world!", new DateTime(2010, 1, 27));

which would fail miserably. The issue is that the TValue in IDictionary<TKey, TValue> is used in both input and output positions. To wit:

myDict.Add(key, value);   

and

TValue value = myDict[key];

So is that a bug or a feature?

It's by design.

Will it ever come, maybe in .NET 37.4?

No, it's inherently unsafe.

Jason
+3  A: 

.NET 4 only supports out covariance not in. It works with IEnumerable because IEnumerable is read only.

Paul Creasey