Possible Duplicate:
In C#, why can't a List<string> object be stored in a List<object> variable
Why doesn't the below work?
List<string> castMe = new List<string>();
IEnumerable<string> getFromCast = (IEnumerable<string>)castMe; // allowed.
Dictionary<int, List<string>> castMeDict = new Dictionary<int, List<string>>();
Dictionary<int, IEnumerable<string>> getFromDict = (Dictionary<int, IEnumerable<string>>)castMeDict; // Not allowed
Is this a flaw in the Dictionary
casting mechanism, or in my thinking that this should be allowed?
Thanks.
One can only put one type of object into a dictionary. If one wants to put a variety of types of data into the same dictionary, e.g. for configuration information or other common data stores, the superclass of all possible held data types must be used to define the dictionary.
The Key value of a Dictionary is unique and doesn't let you add a duplicate key entry.
foreach loop: You can use foreach loop to access the key/value pairs of the dictionary.As shown in the below example we access the Dictionary using a foreach loop.
A Dictionary object contains a set of key-item pairs. A dictionary's item is a value that is unambiguously associated with a unique key and the key is used to retrieve the item. The key can be of any type except a variant or an array (but generally it is a string or still an integer).
Is this a flaw in the Dictionary casting mechanism, or in my thinking that this should be allowed?
In your thinking. You are expecting that dictionaries should be covariant in their conversions. They are not, for the following reason. Suppose they were, and deduce what could go wrong:
Dictionary<int, List<string>> castMeDict =
new Dictionary<int, List<string>>();
Dictionary<int, IEnumerable<string>> getFromDict =
(Dictionary<int, IEnumerable<string>>)castMeDict;
castMeDict[123] = new List<string>();
IEnumerable<string> strings = getFromDict[123]; // No problem!
getFromDict[123] = new string[] { "hello" }; // Big problem!
An array of string is convertible to IEnumerable<string>
but not to List<string>
. You just put something that is not a list of string into a dictionary that can only take list of string.
In C# generic types may be covariant or contravariant if all the following conditions are met:
Most of those conditions are not met for dictionary -- it is not an interface or delegate, it is not provably safe, and the type is not marked as safe for variance. So, no variance for dictionaries.
IEnumerable<T>
by contrast does meet all those conditions. You can convert IEnumerable<string>
to IEnumerable<object>
in C# 4.
If the subject of variance interests you, consider reading my two dozen articles on the subject:
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
Research contravariance and covariance. For a particular example of why such a case could be a bad thing, check this answer by Jon Skeet.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With