Search code examples
c#.netcastingc#-6.0.net-4.6

Why does upcasting IDictionary<TKey, TValue> to IEnumerable<object> fail?


See the following code snippet:

(IEnumerable<object>)new Dictionary<string, string>()

The above cast will throw an invalid cast exception.

Actually, IDictionary<TKey, TValue> also indirectly implements IEnumerable<out T>, because it also implements ICollection<T>. That is, the whole cast should be valid.

In fact, for me it is even more strange that if I run the whole cast on a debugger watch slot, it works!

Enter image description here

What's going on?


Solution

  • That dictionary does implement IEnumerable<KeyValuePair<TKey, TValue>> and IEnumerable, but IEnumerable of a struct is not the same as IEnumerable of an object. Variance only works for reference-types. KeyValuePair<K, V> is a struct and not a class.

    This does work at my end and should be the logical choice:

    var x = (IEnumerable)new Dictionary<string, string>();
    

    As a sample, this does work:

    List<string> l = new List<string>();
    var x = (IEnumerable<object>)l;
    

    But this one doesn't:

    List<DateTime> l2 = new List<DateTime>();
    var x = (IEnumerable<object>)l2;
    

    Clearly indicating the struct is the problem.

    (Why it works in your Watch windows, I don't know)